]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
Use new GtkComboBoxEntry in all tests
[~andy/gtk] / tests / testgtk.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27
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   GtkComboBoxText *cb;
3955   GtkWidget *cb_entry;
3956   GtkWidget *button;
3957   GtkWidget *separator;
3958
3959   if (!window)
3960     {
3961       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3962       gtk_window_set_screen (GTK_WINDOW (window),
3963                              gtk_widget_get_screen (widget));
3964
3965       g_signal_connect (window, "destroy",
3966                         G_CALLBACK (gtk_widget_destroyed),
3967                         &window);
3968
3969       gtk_window_set_title (GTK_WINDOW (window), "entry");
3970       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3971
3972
3973       box1 = gtk_vbox_new (FALSE, 0);
3974       gtk_container_add (GTK_CONTAINER (window), box1);
3975
3976
3977       box2 = gtk_vbox_new (FALSE, 10);
3978       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3979       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3980
3981       hbox = gtk_hbox_new (FALSE, 5);
3982       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
3983       
3984       entry = gtk_entry_new ();
3985       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");
3986       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
3987       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3988
3989       button = gtk_button_new_with_mnemonic ("_Props");
3990       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
3991       g_signal_connect (button, "clicked",
3992                         G_CALLBACK (props_clicked),
3993                         entry);
3994
3995       cb = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
3996
3997       gtk_combo_box_text_append_text (cb, "item0");
3998       gtk_combo_box_text_append_text (cb, "item0");
3999       gtk_combo_box_text_append_text (cb, "item1 item1");
4000       gtk_combo_box_text_append_text (cb, "item2 item2 item2");
4001       gtk_combo_box_text_append_text (cb, "item3 item3 item3 item3");
4002       gtk_combo_box_text_append_text (cb, "item4 item4 item4 item4 item4");
4003       gtk_combo_box_text_append_text (cb, "item5 item5 item5 item5 item5 item5");
4004       gtk_combo_box_text_append_text (cb, "item6 item6 item6 item6 item6");
4005       gtk_combo_box_text_append_text (cb, "item7 item7 item7 item7");
4006       gtk_combo_box_text_append_text (cb, "item8 item8 item8");
4007       gtk_combo_box_text_append_text (cb, "item9 item9");
4008
4009       cb_entry = gtk_bin_get_child (GTK_BIN (cb));
4010       gtk_entry_set_text (GTK_ENTRY (cb_entry), "hello world \n\n\n foo");
4011       gtk_editable_select_region (GTK_EDITABLE (cb_entry), 0, -1);
4012       gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (cb), TRUE, TRUE, 0);
4013
4014       sensitive_check = gtk_check_button_new_with_label("Sensitive");
4015       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
4016       g_signal_connect (sensitive_check, "toggled",
4017                         G_CALLBACK (entry_toggle_sensitive), entry);
4018       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
4019
4020       has_frame_check = gtk_check_button_new_with_label("Has Frame");
4021       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
4022       g_signal_connect (has_frame_check, "toggled",
4023                         G_CALLBACK (entry_toggle_frame), entry);
4024       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
4025
4026       progress_check = gtk_check_button_new_with_label("Show Progress");
4027       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
4028       g_signal_connect (progress_check, "toggled",
4029                         G_CALLBACK (entry_toggle_progress), entry);
4030
4031       progress_check = gtk_check_button_new_with_label("Pulse Progress");
4032       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
4033       g_signal_connect (progress_check, "toggled",
4034                         G_CALLBACK (entry_toggle_pulse), entry);
4035
4036       separator = gtk_hseparator_new ();
4037       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4038
4039       box2 = gtk_vbox_new (FALSE, 10);
4040       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4041       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4042
4043       button = gtk_button_new_with_label ("close");
4044       g_signal_connect_swapped (button, "clicked",
4045                                 G_CALLBACK (gtk_widget_destroy),
4046                                 window);
4047       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4048       gtk_widget_set_can_default (button, TRUE);
4049       gtk_widget_grab_default (button);
4050     }
4051
4052   if (!gtk_widget_get_visible (window))
4053     gtk_widget_show_all (window);
4054   else
4055     gtk_widget_destroy (window);
4056 }
4057
4058 static void
4059 create_expander (GtkWidget *widget)
4060 {
4061   GtkWidget *box1;
4062   GtkWidget *expander;
4063   GtkWidget *hidden;
4064   static GtkWidget *window = NULL;
4065
4066   if (!window)
4067     {
4068       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4069       gtk_window_set_screen (GTK_WINDOW (window),
4070                              gtk_widget_get_screen (widget));
4071       
4072       g_signal_connect (window, "destroy",
4073                         G_CALLBACK (gtk_widget_destroyed),
4074                         &window);
4075       
4076       gtk_window_set_title (GTK_WINDOW (window), "expander");
4077       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4078       
4079       box1 = gtk_vbox_new (FALSE, 0);
4080       gtk_container_add (GTK_CONTAINER (window), box1);
4081       
4082       expander = gtk_expander_new ("The Hidden");
4083       
4084       gtk_box_pack_start (GTK_BOX (box1), expander, TRUE, TRUE, 0);
4085       
4086       hidden = gtk_label_new ("Revealed!");
4087       
4088       gtk_container_add (GTK_CONTAINER (expander), hidden);
4089     }
4090   
4091   if (!gtk_widget_get_visible (window))
4092     gtk_widget_show_all (window);
4093   else
4094     gtk_widget_destroy (window);
4095 }
4096
4097
4098 /* GtkEventBox */
4099
4100
4101 static void
4102 event_box_label_pressed (GtkWidget        *widget,
4103                          GdkEventButton   *event,
4104                          gpointer user_data)
4105 {
4106   g_print ("clicked on event box\n");
4107 }
4108
4109 static void
4110 event_box_button_clicked (GtkWidget *widget,
4111                           GtkWidget *button,
4112                           gpointer user_data)
4113 {
4114   g_print ("pushed button\n");
4115 }
4116
4117 static void
4118 event_box_toggle_visible_window (GtkWidget *checkbutton,
4119                                  GtkEventBox *event_box)
4120 {
4121   gtk_event_box_set_visible_window (event_box,
4122                                     GTK_TOGGLE_BUTTON(checkbutton)->active);
4123 }
4124
4125 static void
4126 event_box_toggle_above_child (GtkWidget *checkbutton,
4127                               GtkEventBox *event_box)
4128 {
4129   gtk_event_box_set_above_child (event_box,
4130                                  GTK_TOGGLE_BUTTON(checkbutton)->active);
4131 }
4132
4133 static void
4134 create_event_box (GtkWidget *widget)
4135 {
4136   static GtkWidget *window = NULL;
4137   GtkWidget *box1;
4138   GtkWidget *box2;
4139   GtkWidget *hbox;
4140   GtkWidget *vbox;
4141   GtkWidget *button;
4142   GtkWidget *separator;
4143   GtkWidget *event_box;
4144   GtkWidget *label;
4145   GtkWidget *visible_window_check;
4146   GtkWidget *above_child_check;
4147   GdkColor color;
4148
4149   if (!window)
4150     {
4151       color.red = 0;
4152       color.blue = 65535;
4153       color.green = 0;
4154       
4155       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4156       gtk_window_set_screen (GTK_WINDOW (window),
4157                              gtk_widget_get_screen (widget));
4158
4159       g_signal_connect (window, "destroy",
4160                         G_CALLBACK (gtk_widget_destroyed),
4161                         &window);
4162
4163       gtk_window_set_title (GTK_WINDOW (window), "event box");
4164       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4165
4166       box1 = gtk_vbox_new (FALSE, 0);
4167       gtk_container_add (GTK_CONTAINER (window), box1);
4168       gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &color);
4169
4170       hbox = gtk_hbox_new (FALSE, 0);
4171       gtk_box_pack_start (GTK_BOX (box1), hbox, TRUE, FALSE, 0);
4172       
4173       event_box = gtk_event_box_new ();
4174       gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, FALSE, 0);
4175
4176       vbox = gtk_vbox_new (FALSE, 0);
4177       gtk_container_add (GTK_CONTAINER (event_box), vbox);
4178       g_signal_connect (event_box, "button_press_event",
4179                         G_CALLBACK (event_box_label_pressed),
4180                         NULL);
4181       
4182       label = gtk_label_new ("Click on this label");
4183       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
4184
4185       button = gtk_button_new_with_label ("button in eventbox");
4186       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, FALSE, 0);
4187       g_signal_connect (button, "clicked",
4188                         G_CALLBACK (event_box_button_clicked),
4189                         NULL);
4190       
4191
4192       visible_window_check = gtk_check_button_new_with_label("Visible Window");
4193       gtk_box_pack_start (GTK_BOX (box1), visible_window_check, FALSE, TRUE, 0);
4194       g_signal_connect (visible_window_check, "toggled",
4195                         G_CALLBACK (event_box_toggle_visible_window), event_box);
4196       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visible_window_check), FALSE);
4197       
4198       above_child_check = gtk_check_button_new_with_label("Above Child");
4199       gtk_box_pack_start (GTK_BOX (box1), above_child_check, FALSE, TRUE, 0);
4200       g_signal_connect (above_child_check, "toggled",
4201                         G_CALLBACK (event_box_toggle_above_child), event_box);
4202       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (above_child_check), FALSE);
4203       
4204       separator = gtk_hseparator_new ();
4205       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4206
4207       box2 = gtk_vbox_new (FALSE, 10);
4208       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4209       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4210
4211       button = gtk_button_new_with_label ("close");
4212       g_signal_connect_swapped (button, "clicked",
4213                                 G_CALLBACK (gtk_widget_destroy),
4214                                 window);
4215       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4216       gtk_widget_set_can_default (button, TRUE);
4217       gtk_widget_grab_default (button);
4218     }
4219
4220   if (!gtk_widget_get_visible (window))
4221     gtk_widget_show_all (window);
4222   else
4223     gtk_widget_destroy (window);
4224 }
4225
4226
4227 /*
4228  * GtkSizeGroup
4229  */
4230
4231 #define SIZE_GROUP_INITIAL_SIZE 50
4232
4233 static void
4234 size_group_hsize_changed (GtkSpinButton *spin_button,
4235                           GtkWidget     *button)
4236 {
4237   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4238                                gtk_spin_button_get_value_as_int (spin_button),
4239                                -1);
4240 }
4241
4242 static void
4243 size_group_vsize_changed (GtkSpinButton *spin_button,
4244                           GtkWidget     *button)
4245 {
4246   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4247                                -1,
4248                                gtk_spin_button_get_value_as_int (spin_button));
4249 }
4250
4251 static GtkWidget *
4252 create_size_group_window (GdkScreen    *screen,
4253                           GtkSizeGroup *master_size_group)
4254 {
4255   GtkWidget *content_area;
4256   GtkWidget *window;
4257   GtkWidget *table;
4258   GtkWidget *main_button;
4259   GtkWidget *button;
4260   GtkWidget *spin_button;
4261   GtkWidget *hbox;
4262   GtkSizeGroup *hgroup1;
4263   GtkSizeGroup *hgroup2;
4264   GtkSizeGroup *vgroup1;
4265   GtkSizeGroup *vgroup2;
4266
4267   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4268                                         NULL, 0,
4269                                         GTK_STOCK_CLOSE,
4270                                         GTK_RESPONSE_NONE,
4271                                         NULL);
4272
4273   gtk_window_set_screen (GTK_WINDOW (window), screen);
4274
4275   gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
4276
4277   g_signal_connect (window, "response",
4278                     G_CALLBACK (gtk_widget_destroy),
4279                     NULL);
4280
4281   content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
4282
4283   table = gtk_table_new (2, 2, FALSE);
4284   gtk_box_pack_start (GTK_BOX (content_area), table, TRUE, TRUE, 0);
4285
4286   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
4287   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
4288   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
4289   gtk_widget_set_size_request (table, 250, 250);
4290
4291   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4292   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4293   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4294   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4295
4296   main_button = gtk_button_new_with_label ("X");
4297   
4298   gtk_table_attach (GTK_TABLE (table), main_button,
4299                     0, 1,       0, 1,
4300                     GTK_EXPAND, GTK_EXPAND,
4301                     0,          0);
4302   gtk_size_group_add_widget (master_size_group, main_button);
4303   gtk_size_group_add_widget (hgroup1, main_button);
4304   gtk_size_group_add_widget (vgroup1, main_button);
4305   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (main_button)),
4306                                SIZE_GROUP_INITIAL_SIZE,
4307                                SIZE_GROUP_INITIAL_SIZE);
4308
4309   button = gtk_button_new ();
4310   gtk_table_attach (GTK_TABLE (table), button,
4311                     1, 2,       0, 1,
4312                     GTK_EXPAND, GTK_EXPAND,
4313                     0,          0);
4314   gtk_size_group_add_widget (vgroup1, button);
4315   gtk_size_group_add_widget (vgroup2, button);
4316
4317   button = gtk_button_new ();
4318   gtk_table_attach (GTK_TABLE (table), button,
4319                     0, 1,       1, 2,
4320                     GTK_EXPAND, GTK_EXPAND,
4321                     0,          0);
4322   gtk_size_group_add_widget (hgroup1, button);
4323   gtk_size_group_add_widget (hgroup2, button);
4324
4325   button = gtk_button_new ();
4326   gtk_table_attach (GTK_TABLE (table), button,
4327                     1, 2,       1, 2,
4328                     GTK_EXPAND, GTK_EXPAND,
4329                     0,          0);
4330   gtk_size_group_add_widget (hgroup2, button);
4331   gtk_size_group_add_widget (vgroup2, button);
4332
4333   g_object_unref (hgroup1);
4334   g_object_unref (hgroup2);
4335   g_object_unref (vgroup1);
4336   g_object_unref (vgroup2);
4337   
4338   hbox = gtk_hbox_new (FALSE, 5);
4339   gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
4340   
4341   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4342   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4343   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4344   g_signal_connect (spin_button, "value_changed",
4345                     G_CALLBACK (size_group_hsize_changed), main_button);
4346
4347   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4348   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4349   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4350   g_signal_connect (spin_button, "value_changed",
4351                     G_CALLBACK (size_group_vsize_changed), main_button);
4352
4353   return window;
4354 }
4355
4356 static void
4357 create_size_groups (GtkWidget *widget)
4358 {
4359   static GtkWidget *window1 = NULL;
4360   static GtkWidget *window2 = NULL;
4361   static GtkSizeGroup *master_size_group;
4362
4363   if (!master_size_group)
4364     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4365
4366   if (!window1)
4367     {
4368       window1 = create_size_group_window (gtk_widget_get_screen (widget),
4369                                           master_size_group);
4370
4371       g_signal_connect (window1, "destroy",
4372                         G_CALLBACK (gtk_widget_destroyed),
4373                         &window1);
4374     }
4375
4376   if (!window2)
4377     {
4378       window2 = create_size_group_window (gtk_widget_get_screen (widget),
4379                                           master_size_group);
4380
4381       g_signal_connect (window2, "destroy",
4382                         G_CALLBACK (gtk_widget_destroyed),
4383                         &window2);
4384     }
4385
4386   if (gtk_widget_get_visible (window1) && gtk_widget_get_visible (window2))
4387     {
4388       gtk_widget_destroy (window1);
4389       gtk_widget_destroy (window2);
4390     }
4391   else
4392     {
4393       if (!gtk_widget_get_visible (window1))
4394         gtk_widget_show_all (window1);
4395       if (!gtk_widget_get_visible (window2))
4396         gtk_widget_show_all (window2);
4397     }
4398 }
4399
4400 /*
4401  * GtkSpinButton
4402  */
4403
4404 static GtkWidget *spinner1;
4405
4406 static void
4407 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4408 {
4409   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
4410 }
4411
4412 static void
4413 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4414 {
4415   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
4416 }
4417
4418 static void
4419 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4420 {
4421   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4422                               gtk_spin_button_get_value_as_int (spin));
4423 }
4424
4425 static void
4426 get_value (GtkWidget *widget, gpointer data)
4427 {
4428   gchar buf[32];
4429   GtkLabel *label;
4430   GtkSpinButton *spin;
4431
4432   spin = GTK_SPIN_BUTTON (spinner1);
4433   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4434   if (GPOINTER_TO_INT (data) == 1)
4435     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4436   else
4437     sprintf (buf, "%0.*f",
4438              gtk_spin_button_get_digits (spin),
4439              gtk_spin_button_get_value (spin));
4440
4441   gtk_label_set_text (label, buf);
4442 }
4443
4444 static void
4445 get_spin_value (GtkWidget *widget, gpointer data)
4446 {
4447   gchar *buffer;
4448   GtkLabel *label;
4449   GtkSpinButton *spin;
4450
4451   spin = GTK_SPIN_BUTTON (widget);
4452   label = GTK_LABEL (data);
4453
4454   buffer = g_strdup_printf ("%0.*f",
4455                             gtk_spin_button_get_digits (spin),
4456                             gtk_spin_button_get_value (spin));
4457   gtk_label_set_text (label, buffer);
4458
4459   g_free (buffer);
4460 }
4461
4462 static gint
4463 spin_button_time_output_func (GtkSpinButton *spin_button)
4464 {
4465   GtkAdjustment *adjustment;
4466   static gchar buf[6];
4467   gdouble hours;
4468   gdouble minutes;
4469
4470   adjustment = gtk_spin_button_get_adjustment (spin_button);
4471   hours = gtk_adjustment_get_value (adjustment) / 60.0;
4472   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4473   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4474   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4475     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4476   return TRUE;
4477 }
4478
4479 static gint
4480 spin_button_month_input_func (GtkSpinButton *spin_button,
4481                               gdouble       *new_val)
4482 {
4483   gint i;
4484   static gchar *month[12] = { "January", "February", "March", "April",
4485                               "May", "June", "July", "August",
4486                               "September", "October", "November", "December" };
4487   gchar *tmp1, *tmp2;
4488   gboolean found = FALSE;
4489
4490   for (i = 1; i <= 12; i++)
4491     {
4492       tmp1 = g_ascii_strup (month[i - 1], -1);
4493       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4494       if (strstr (tmp1, tmp2) == tmp1)
4495         found = TRUE;
4496       g_free (tmp1);
4497       g_free (tmp2);
4498       if (found)
4499         break;
4500     }
4501   if (!found)
4502     {
4503       *new_val = 0.0;
4504       return GTK_INPUT_ERROR;
4505     }
4506   *new_val = (gdouble) i;
4507   return TRUE;
4508 }
4509
4510 static gint
4511 spin_button_month_output_func (GtkSpinButton *spin_button)
4512 {
4513   GtkAdjustment *adjustment;
4514   gdouble value;
4515   gint i;
4516   static gchar *month[12] = { "January", "February", "March", "April",
4517                               "May", "June", "July", "August", "September",
4518                               "October", "November", "December" };
4519
4520   adjustment = gtk_spin_button_get_adjustment (spin_button);
4521   value = gtk_adjustment_get_value (adjustment);
4522   for (i = 1; i <= 12; i++)
4523     if (fabs (value - (double)i) < 1e-5)
4524       {
4525         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4526           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4527       }
4528   return TRUE;
4529 }
4530
4531 static gint
4532 spin_button_hex_input_func (GtkSpinButton *spin_button,
4533                             gdouble       *new_val)
4534 {
4535   const gchar *buf;
4536   gchar *err;
4537   gdouble res;
4538
4539   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4540   res = strtol(buf, &err, 16);
4541   *new_val = res;
4542   if (*err)
4543     return GTK_INPUT_ERROR;
4544   else
4545     return TRUE;
4546 }
4547
4548 static gint
4549 spin_button_hex_output_func (GtkSpinButton *spin_button)
4550 {
4551   GtkAdjustment *adjustment;
4552   static gchar buf[7];
4553   gint val;
4554
4555   adjustment = gtk_spin_button_get_adjustment (spin_button);
4556   val = (gint) gtk_adjustment_get_value (adjustment);
4557   if (fabs (val) < 1e-5)
4558     sprintf (buf, "0x00");
4559   else
4560     sprintf (buf, "0x%.2X", val);
4561   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4562     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4563   return TRUE;
4564 }
4565
4566 static void
4567 create_spins (GtkWidget *widget)
4568 {
4569   static GtkWidget *window = NULL;
4570   GtkWidget *frame;
4571   GtkWidget *hbox;
4572   GtkWidget *main_vbox;
4573   GtkWidget *vbox;
4574   GtkWidget *vbox2;
4575   GtkWidget *spinner2;
4576   GtkWidget *spinner;
4577   GtkWidget *button;
4578   GtkWidget *label;
4579   GtkWidget *val_label;
4580   GtkAdjustment *adj;
4581
4582   if (!window)
4583     {
4584       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4585       gtk_window_set_screen (GTK_WINDOW (window),
4586                              gtk_widget_get_screen (widget));
4587       
4588       g_signal_connect (window, "destroy",
4589                         G_CALLBACK (gtk_widget_destroyed),
4590                         &window);
4591       
4592       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4593       
4594       main_vbox = gtk_vbox_new (FALSE, 5);
4595       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4596       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4597       
4598       frame = gtk_frame_new ("Not accelerated");
4599       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4600       
4601       vbox = gtk_vbox_new (FALSE, 0);
4602       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4603       gtk_container_add (GTK_CONTAINER (frame), vbox);
4604       
4605       /* Time, month, hex spinners */
4606       
4607       hbox = gtk_hbox_new (FALSE, 0);
4608       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4609       
4610       vbox2 = gtk_vbox_new (FALSE, 0);
4611       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4612       
4613       label = gtk_label_new ("Time :");
4614       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4615       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4616
4617       adj = gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4618       spinner = gtk_spin_button_new (adj, 0, 0);
4619       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4620       g_signal_connect (spinner,
4621                         "output",
4622                         G_CALLBACK (spin_button_time_output_func),
4623                         NULL);
4624       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4625       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 5);
4626       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4627
4628       vbox2 = gtk_vbox_new (FALSE, 0);
4629       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4630       
4631       label = gtk_label_new ("Month :");
4632       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4633       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4634
4635       adj = gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4636                                                   5.0, 0.0);
4637       spinner = gtk_spin_button_new (adj, 0, 0);
4638       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4639                                          GTK_UPDATE_IF_VALID);
4640       g_signal_connect (spinner,
4641                         "input",
4642                         G_CALLBACK (spin_button_month_input_func),
4643                         NULL);
4644       g_signal_connect (spinner,
4645                         "output",
4646                         G_CALLBACK (spin_button_month_output_func),
4647                         NULL);
4648       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4649       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 9);
4650       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4651       
4652       vbox2 = gtk_vbox_new (FALSE, 0);
4653       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4654
4655       label = gtk_label_new ("Hex :");
4656       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4657       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4658
4659       adj = gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4660       spinner = gtk_spin_button_new (adj, 0, 0);
4661       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4662       g_signal_connect (spinner,
4663                         "input",
4664                         G_CALLBACK (spin_button_hex_input_func),
4665                         NULL);
4666       g_signal_connect (spinner,
4667                         "output",
4668                         G_CALLBACK (spin_button_hex_output_func),
4669                         NULL);
4670       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4671       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 4);
4672       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4673
4674       frame = gtk_frame_new ("Accelerated");
4675       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4676   
4677       vbox = gtk_vbox_new (FALSE, 0);
4678       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4679       gtk_container_add (GTK_CONTAINER (frame), vbox);
4680       
4681       hbox = gtk_hbox_new (FALSE, 0);
4682       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4683       
4684       vbox2 = gtk_vbox_new (FALSE, 0);
4685       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4686       
4687       label = gtk_label_new ("Value :");
4688       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4689       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4690
4691       adj = gtk_adjustment_new (0.0, -10000.0, 10000.0,
4692                                                   0.5, 100.0, 0.0);
4693       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
4694       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4695       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4696
4697       vbox2 = gtk_vbox_new (FALSE, 0);
4698       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4699
4700       label = gtk_label_new ("Digits :");
4701       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4702       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4703
4704       adj = gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4705       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
4706       g_signal_connect (adj, "value_changed",
4707                         G_CALLBACK (change_digits),
4708                         spinner2);
4709       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4710
4711       hbox = gtk_hbox_new (FALSE, 0);
4712       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4713
4714       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4715       g_signal_connect (button, "clicked",
4716                         G_CALLBACK (toggle_snap),
4717                         spinner1);
4718       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4719       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4720
4721       button = gtk_check_button_new_with_label ("Numeric only input mode");
4722       g_signal_connect (button, "clicked",
4723                         G_CALLBACK (toggle_numeric),
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       val_label = gtk_label_new ("");
4729
4730       hbox = gtk_hbox_new (FALSE, 0);
4731       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4732
4733       button = gtk_button_new_with_label ("Value as Int");
4734       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4735       g_signal_connect (button, "clicked",
4736                         G_CALLBACK (get_value),
4737                         GINT_TO_POINTER (1));
4738       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4739
4740       button = gtk_button_new_with_label ("Value as Float");
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 (2));
4745       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4746
4747       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4748       gtk_label_set_text (GTK_LABEL (val_label), "0");
4749
4750       frame = gtk_frame_new ("Using Convenience Constructor");
4751       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4752   
4753       hbox = gtk_hbox_new (FALSE, 0);
4754       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4755       gtk_container_add (GTK_CONTAINER (frame), hbox);
4756       
4757       val_label = gtk_label_new ("0.0");
4758
4759       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4760       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4761       g_signal_connect (spinner, "value_changed",
4762                         G_CALLBACK (get_spin_value), val_label);
4763       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4764       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4765
4766       hbox = gtk_hbox_new (FALSE, 0);
4767       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4768   
4769       button = gtk_button_new_with_label ("Close");
4770       g_signal_connect_swapped (button, "clicked",
4771                                 G_CALLBACK (gtk_widget_destroy),
4772                                 window);
4773       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4774     }
4775
4776   if (!gtk_widget_get_visible (window))
4777     gtk_widget_show_all (window);
4778   else
4779     gtk_widget_destroy (window);
4780 }
4781
4782
4783 /*
4784  * Cursors
4785  */
4786
4787 static gint
4788 cursor_draw (GtkWidget *widget,
4789              cairo_t   *cr,
4790              gpointer   user_data)
4791 {
4792   int width, height;
4793
4794   width = gtk_widget_get_allocated_width (widget);
4795   height = gtk_widget_get_allocated_height (widget);
4796
4797   cairo_set_source_rgb (cr, 1, 1, 1);
4798   cairo_rectangle (cr, 0, 0, width, height / 2);
4799   cairo_fill (cr);
4800
4801   cairo_set_source_rgb (cr, 0, 0, 0);
4802   cairo_rectangle (cr, 0, height / 2, width, height / 2);
4803   cairo_fill (cr);
4804
4805   gdk_cairo_set_source_color (cr, &gtk_widget_get_style (widget)->bg[GTK_STATE_NORMAL]);
4806   cairo_rectangle (cr, width / 3, height / 3, width / 3, height / 3);
4807   cairo_fill (cr);
4808
4809   return TRUE;
4810 }
4811
4812 static void
4813 set_cursor (GtkWidget *spinner,
4814             GtkWidget *widget)
4815 {
4816   guint c;
4817   GdkCursor *cursor;
4818   GtkWidget *label;
4819   GEnumClass *class;
4820   GEnumValue *vals;
4821
4822   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
4823   c &= 0xfe;
4824
4825   label = g_object_get_data (G_OBJECT (spinner), "user_data");
4826   
4827   class = g_type_class_ref (GDK_TYPE_CURSOR_TYPE);
4828   vals = class->values;
4829
4830   while (vals && vals->value != c)
4831     vals++;
4832   if (vals)
4833     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
4834   else
4835     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
4836
4837   g_type_class_unref (class);
4838
4839   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
4840   gdk_window_set_cursor (gtk_widget_get_window (widget),
4841                          cursor);
4842   gdk_cursor_unref (cursor);
4843 }
4844
4845 static gint
4846 cursor_event (GtkWidget          *widget,
4847               GdkEvent           *event,
4848               GtkSpinButton      *spinner)
4849 {
4850   if ((event->type == GDK_BUTTON_PRESS) &&
4851       ((event->button.button == 1) ||
4852        (event->button.button == 3)))
4853     {
4854       gtk_spin_button_spin (spinner, event->button.button == 1 ?
4855                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
4856       return TRUE;
4857     }
4858
4859   return FALSE;
4860 }
4861
4862 #ifdef GDK_WINDOWING_X11
4863 #include "x11/gdkx.h"
4864
4865 static void
4866 change_cursor_theme (GtkWidget *widget,
4867                      gpointer   data)
4868 {
4869   const gchar *theme;
4870   gint size;
4871   GList *children;
4872
4873   children = gtk_container_get_children (GTK_CONTAINER (data));
4874
4875   theme = gtk_entry_get_text (GTK_ENTRY (children->next->data));
4876   size = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (children->next->next->data));
4877
4878   g_list_free (children);
4879
4880   gdk_x11_display_set_cursor_theme (gtk_widget_get_display (widget),
4881                                     theme, size);
4882 }
4883 #endif
4884
4885
4886 static void
4887 create_cursors (GtkWidget *widget)
4888 {
4889   static GtkWidget *window = NULL;
4890   GtkWidget *frame;
4891   GtkWidget *hbox;
4892   GtkWidget *main_vbox;
4893   GtkWidget *vbox;
4894   GtkWidget *darea;
4895   GtkWidget *spinner;
4896   GtkWidget *button;
4897   GtkWidget *label;
4898   GtkWidget *any;
4899   GtkAdjustment *adj;
4900   GtkWidget *entry;
4901   GtkWidget *size;  
4902
4903   if (!window)
4904     {
4905       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4906       gtk_window_set_screen (GTK_WINDOW (window), 
4907                              gtk_widget_get_screen (widget));
4908       
4909       g_signal_connect (window, "destroy",
4910                         G_CALLBACK (gtk_widget_destroyed),
4911                         &window);
4912       
4913       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
4914       
4915       main_vbox = gtk_vbox_new (FALSE, 5);
4916       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
4917       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4918
4919       vbox =
4920         g_object_new (gtk_vbox_get_type (),
4921                         "GtkBox::homogeneous", FALSE,
4922                         "GtkBox::spacing", 5,
4923                         "GtkContainer::border_width", 10,
4924                         "GtkWidget::parent", main_vbox,
4925                         "GtkWidget::visible", TRUE,
4926                         NULL);
4927
4928 #ifdef GDK_WINDOWING_X11
4929       hbox = gtk_hbox_new (FALSE, 0);
4930       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4931       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4932
4933       label = gtk_label_new ("Cursor Theme : ");
4934       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4935       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4936
4937       entry = gtk_entry_new ();
4938       gtk_entry_set_text (GTK_ENTRY (entry), "default");
4939       gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
4940
4941       size = gtk_spin_button_new_with_range (1.0, 64.0, 1.0);
4942       gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), 24.0);
4943       gtk_box_pack_start (GTK_BOX (hbox), size, TRUE, TRUE, 0);
4944       
4945       g_signal_connect (entry, "changed", 
4946                         G_CALLBACK (change_cursor_theme), hbox);
4947       g_signal_connect (size, "changed", 
4948                         G_CALLBACK (change_cursor_theme), hbox);
4949 #endif
4950
4951       hbox = gtk_hbox_new (FALSE, 0);
4952       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4953       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4954
4955       label = gtk_label_new ("Cursor Value : ");
4956       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
4957       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4958
4959       adj = gtk_adjustment_new (0,
4960                                 0, 152,
4961                                 2,
4962                                 10, 0);
4963       spinner = gtk_spin_button_new (adj, 0, 0);
4964       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
4965
4966       frame =
4967         g_object_new (gtk_frame_get_type (),
4968                         "GtkFrame::label_xalign", 0.5,
4969                         "GtkFrame::label", "Cursor Area",
4970                         "GtkContainer::border_width", 10,
4971                         "GtkWidget::parent", vbox,
4972                         "GtkWidget::visible", TRUE,
4973                         NULL);
4974
4975       darea = gtk_drawing_area_new ();
4976       gtk_widget_set_size_request (darea, 80, 80);
4977       gtk_container_add (GTK_CONTAINER (frame), darea);
4978       g_signal_connect (darea,
4979                         "draw",
4980                         G_CALLBACK (cursor_draw),
4981                         NULL);
4982       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
4983       g_signal_connect (darea,
4984                         "button_press_event",
4985                         G_CALLBACK (cursor_event),
4986                         spinner);
4987       gtk_widget_show (darea);
4988
4989       g_signal_connect (spinner, "changed",
4990                         G_CALLBACK (set_cursor),
4991                         darea);
4992
4993       label = g_object_new (GTK_TYPE_LABEL,
4994                               "visible", TRUE,
4995                               "label", "XXX",
4996                               "parent", vbox,
4997                               NULL);
4998       gtk_container_child_set (GTK_CONTAINER (vbox), label,
4999                                "expand", FALSE,
5000                                NULL);
5001       g_object_set_data (G_OBJECT (spinner), "user_data", label);
5002
5003       any =
5004         g_object_new (gtk_hseparator_get_type (),
5005                         "GtkWidget::visible", TRUE,
5006                         NULL);
5007       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
5008   
5009       hbox = gtk_hbox_new (FALSE, 0);
5010       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
5011       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5012
5013       button = gtk_button_new_with_label ("Close");
5014       g_signal_connect_swapped (button, "clicked",
5015                                 G_CALLBACK (gtk_widget_destroy),
5016                                 window);
5017       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5018
5019       gtk_widget_show_all (window);
5020
5021       set_cursor (spinner, darea);
5022     }
5023   else
5024     gtk_widget_destroy (window);
5025 }
5026
5027 /*
5028  * GtkColorSelection
5029  */
5030
5031 void
5032 color_selection_ok (GtkWidget               *w,
5033                     GtkColorSelectionDialog *cs)
5034 {
5035   GtkWidget *colorsel;
5036   GdkColor color;
5037
5038   colorsel = gtk_color_selection_dialog_get_color_selection (cs);
5039
5040   gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5041   gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5042 }
5043
5044 void
5045 color_selection_changed (GtkWidget *w,
5046                          GtkColorSelectionDialog *cs)
5047 {
5048   GtkWidget *colorsel;
5049   GdkColor color;
5050
5051   colorsel = gtk_color_selection_dialog_get_color_selection (cs);
5052   gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5053   gtk_color_selection_set_current_color (GTK_COLOR_SELECTION (colorsel), &color);
5054 }
5055
5056 #if 0 /* unused */
5057 static void
5058 opacity_toggled_cb (GtkWidget *w,
5059                     GtkColorSelectionDialog *cs)
5060 {
5061   GtkColorSelection *colorsel;
5062
5063   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
5064   gtk_color_selection_set_has_opacity_control (colorsel,
5065                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
5066 }
5067
5068 static void
5069 palette_toggled_cb (GtkWidget *w,
5070                     GtkColorSelectionDialog *cs)
5071 {
5072   GtkColorSelection *colorsel;
5073
5074   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
5075   gtk_color_selection_set_has_palette (colorsel,
5076                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
5077 }
5078 #endif
5079
5080 void
5081 create_color_selection (GtkWidget *widget)
5082 {
5083   static GtkWidget *window = NULL;
5084
5085   if (!window)
5086     {
5087       GtkWidget *picker;
5088       GtkWidget *hbox;
5089       GtkWidget *label;
5090       GtkWidget *button;
5091       
5092       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5093       gtk_window_set_screen (GTK_WINDOW (window), 
5094                              gtk_widget_get_screen (widget));
5095                              
5096       g_signal_connect (window, "destroy",
5097                         G_CALLBACK (gtk_widget_destroyed),
5098                         &window);
5099
5100       gtk_window_set_title (GTK_WINDOW (window), "GtkColorButton");
5101       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5102
5103       hbox = gtk_hbox_new (FALSE, 8);
5104       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5105       gtk_container_add (GTK_CONTAINER (window), hbox);
5106       
5107       label = gtk_label_new ("Pick a color");
5108       gtk_container_add (GTK_CONTAINER (hbox), label);
5109
5110       picker = gtk_color_button_new ();
5111       gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (picker), TRUE);
5112       gtk_container_add (GTK_CONTAINER (hbox), picker);
5113
5114       button = gtk_button_new_with_mnemonic ("_Props");
5115       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
5116       g_signal_connect (button, "clicked",
5117                         G_CALLBACK (props_clicked),
5118                         picker);
5119     }
5120
5121   if (!gtk_widget_get_visible (window))
5122     gtk_widget_show_all (window);
5123   else
5124     gtk_widget_destroy (window);
5125 }
5126
5127 void
5128 flipping_toggled_cb (GtkWidget *widget, gpointer data)
5129 {
5130   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
5131   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
5132
5133   gtk_widget_set_default_direction (new_direction);
5134 }
5135
5136 static void
5137 orientable_toggle_orientation (GtkOrientable *orientable)
5138 {
5139   GtkOrientation orientation;
5140
5141   orientation = gtk_orientable_get_orientation (orientable);
5142   gtk_orientable_set_orientation (orientable,
5143                                   orientation == GTK_ORIENTATION_HORIZONTAL ?
5144                                   GTK_ORIENTATION_VERTICAL :
5145                                   GTK_ORIENTATION_HORIZONTAL);
5146
5147   if (GTK_IS_CONTAINER (orientable))
5148     {
5149       GList *children;
5150       GList *child;
5151
5152       children = gtk_container_get_children (GTK_CONTAINER (orientable));
5153
5154       for (child = children; child; child = child->next)
5155         {
5156           if (GTK_IS_ORIENTABLE (child->data))
5157             orientable_toggle_orientation (child->data);
5158         }
5159
5160       g_list_free (children);
5161     }
5162 }
5163
5164 void
5165 flipping_orientation_toggled_cb (GtkWidget *widget, gpointer data)
5166 {
5167   GtkWidget *content_area;
5168   GtkWidget *toplevel;
5169
5170   toplevel = gtk_widget_get_toplevel (widget);
5171   content_area = gtk_dialog_get_content_area (GTK_DIALOG (toplevel));
5172   orientable_toggle_orientation (GTK_ORIENTABLE (content_area));
5173 }
5174
5175 static void
5176 set_direction_recurse (GtkWidget *widget,
5177                        gpointer   data)
5178 {
5179   GtkTextDirection *dir = data;
5180   
5181   gtk_widget_set_direction (widget, *dir);
5182   if (GTK_IS_CONTAINER (widget))
5183     gtk_container_foreach (GTK_CONTAINER (widget),
5184                            set_direction_recurse,
5185                            data);
5186 }
5187
5188 static GtkWidget *
5189 create_forward_back (const char       *title,
5190                      GtkTextDirection  text_dir)
5191 {
5192   GtkWidget *frame = gtk_frame_new (title);
5193   GtkWidget *bbox = gtk_hbutton_box_new ();
5194   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
5195   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
5196
5197   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
5198   
5199   gtk_container_add (GTK_CONTAINER (frame), bbox);
5200   gtk_container_add (GTK_CONTAINER (bbox), back_button);
5201   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
5202
5203   set_direction_recurse (frame, &text_dir);
5204
5205   return frame;
5206 }
5207
5208 void
5209 create_flipping (GtkWidget *widget)
5210 {
5211   static GtkWidget *window = NULL;
5212   GtkWidget *check_button, *button;
5213   GtkWidget *action_area, *content_area;
5214
5215   if (!window)
5216     {
5217       window = gtk_dialog_new ();
5218
5219       gtk_window_set_screen (GTK_WINDOW (window),
5220                              gtk_widget_get_screen (widget));
5221
5222       g_signal_connect (window, "destroy",
5223                         G_CALLBACK (gtk_widget_destroyed),
5224                         &window);
5225
5226       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5227       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
5228
5229       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
5230
5231       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
5232       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5233       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5234
5235       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
5236         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
5237
5238       g_signal_connect (check_button, "toggled",
5239                         G_CALLBACK (flipping_toggled_cb), NULL);
5240
5241       check_button = gtk_check_button_new_with_label ("Toggle orientation of all boxes");
5242       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5243       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5244
5245       g_signal_connect (check_button, "toggled",
5246                         G_CALLBACK (flipping_orientation_toggled_cb), NULL);
5247
5248       gtk_box_pack_start (GTK_BOX (content_area),
5249                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
5250                           TRUE, TRUE, 0);
5251
5252       gtk_box_pack_start (GTK_BOX (content_area),
5253                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
5254                           TRUE, TRUE, 0);
5255
5256       gtk_box_pack_start (GTK_BOX (content_area),
5257                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
5258                           TRUE, TRUE, 0);
5259
5260       button = gtk_button_new_with_label ("Close");
5261       g_signal_connect_swapped (button, "clicked",
5262                                 G_CALLBACK (gtk_widget_destroy), window);
5263       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5264     }
5265   
5266   if (!gtk_widget_get_visible (window))
5267     gtk_widget_show_all (window);
5268   else
5269     gtk_widget_destroy (window);
5270 }
5271
5272 /*
5273  * Focus test
5274  */
5275
5276 static GtkWidget*
5277 make_focus_table (GList **list)
5278 {
5279   GtkWidget *table;
5280   gint i, j;
5281   
5282   table = gtk_table_new (5, 5, FALSE);
5283
5284   i = 0;
5285   j = 0;
5286
5287   while (i < 5)
5288     {
5289       j = 0;
5290       while (j < 5)
5291         {
5292           GtkWidget *widget;
5293           
5294           if ((i + j) % 2)
5295             widget = gtk_entry_new ();
5296           else
5297             widget = gtk_button_new_with_label ("Foo");
5298
5299           *list = g_list_prepend (*list, widget);
5300           
5301           gtk_table_attach (GTK_TABLE (table),
5302                             widget,
5303                             i, i + 1,
5304                             j, j + 1,
5305                             GTK_EXPAND | GTK_FILL,
5306                             GTK_EXPAND | GTK_FILL,
5307                             5, 5);
5308           
5309           ++j;
5310         }
5311
5312       ++i;
5313     }
5314
5315   *list = g_list_reverse (*list);
5316   
5317   return table;
5318 }
5319
5320 static void
5321 create_focus (GtkWidget *widget)
5322 {
5323   static GtkWidget *window = NULL;
5324   
5325   if (!window)
5326     {
5327       GtkWidget *content_area;
5328       GtkWidget *table;
5329       GtkWidget *frame;
5330       GList *list = NULL;
5331       
5332       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
5333                                             NULL, 0,
5334                                             GTK_STOCK_CLOSE,
5335                                             GTK_RESPONSE_NONE,
5336                                             NULL);
5337
5338       gtk_window_set_screen (GTK_WINDOW (window),
5339                              gtk_widget_get_screen (widget));
5340
5341       g_signal_connect (window, "destroy",
5342                         G_CALLBACK (gtk_widget_destroyed),
5343                         &window);
5344
5345       g_signal_connect (window, "response",
5346                         G_CALLBACK (gtk_widget_destroy),
5347                         NULL);
5348
5349       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5350       
5351       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
5352
5353       frame = gtk_frame_new ("Weird tab focus chain");
5354
5355       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5356       
5357       table = make_focus_table (&list);
5358
5359       gtk_container_add (GTK_CONTAINER (frame), table);
5360
5361       gtk_container_set_focus_chain (GTK_CONTAINER (table),
5362                                      list);
5363
5364       g_list_free (list);
5365       
5366       frame = gtk_frame_new ("Default tab focus chain");
5367
5368       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5369
5370       list = NULL;
5371       table = make_focus_table (&list);
5372
5373       g_list_free (list);
5374       
5375       gtk_container_add (GTK_CONTAINER (frame), table);      
5376     }
5377   
5378   if (!gtk_widget_get_visible (window))
5379     gtk_widget_show_all (window);
5380   else
5381     gtk_widget_destroy (window);
5382 }
5383
5384 /*
5385  * GtkFontSelection
5386  */
5387
5388 void
5389 font_selection_ok (GtkWidget              *w,
5390                    GtkFontSelectionDialog *fs)
5391 {
5392   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
5393
5394   g_print ("%s\n", s);
5395   g_free (s);
5396   gtk_widget_destroy (GTK_WIDGET (fs));
5397 }
5398
5399 void
5400 create_font_selection (GtkWidget *widget)
5401 {
5402   static GtkWidget *window = NULL;
5403
5404   if (!window)
5405     {
5406       GtkWidget *picker;
5407       GtkWidget *hbox;
5408       GtkWidget *label;
5409       
5410       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5411       gtk_window_set_screen (GTK_WINDOW (window),
5412                              gtk_widget_get_screen (widget));
5413
5414       g_signal_connect (window, "destroy",
5415                         G_CALLBACK (gtk_widget_destroyed),
5416                         &window);
5417
5418       gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
5419       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5420
5421       hbox = gtk_hbox_new (FALSE, 8);
5422       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5423       gtk_container_add (GTK_CONTAINER (window), hbox);
5424       
5425       label = gtk_label_new ("Pick a font");
5426       gtk_container_add (GTK_CONTAINER (hbox), label);
5427
5428       picker = gtk_font_button_new ();
5429       gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
5430       gtk_container_add (GTK_CONTAINER (hbox), picker);
5431     }
5432   
5433   if (!gtk_widget_get_visible (window))
5434     gtk_widget_show_all (window);
5435   else
5436     gtk_widget_destroy (window);
5437 }
5438
5439 /*
5440  * GtkDialog
5441  */
5442
5443 static GtkWidget *dialog_window = NULL;
5444
5445 static void
5446 label_toggle (GtkWidget  *widget,
5447               GtkWidget **label)
5448 {
5449   if (!(*label))
5450     {
5451       *label = gtk_label_new ("Dialog Test");
5452       g_signal_connect (*label,
5453                         "destroy",
5454                         G_CALLBACK (gtk_widget_destroyed),
5455                         label);
5456       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
5457       gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog_window))),
5458                           *label, TRUE, TRUE, 0);
5459       gtk_widget_show (*label);
5460     }
5461   else
5462     gtk_widget_destroy (*label);
5463 }
5464
5465 static void
5466 create_dialog (GtkWidget *widget)
5467 {
5468   static GtkWidget *label;
5469   GtkWidget *action_area;
5470   GtkWidget *button;
5471
5472   if (!dialog_window)
5473     {
5474       /* This is a terrible example; it's much simpler to create
5475        * dialogs than this. Don't use testgtk for example code,
5476        * use gtk-demo ;-)
5477        */
5478       
5479       dialog_window = gtk_dialog_new ();
5480       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5481                              gtk_widget_get_screen (widget));
5482
5483       g_signal_connect (dialog_window, "destroy",
5484                         G_CALLBACK (gtk_widget_destroyed),
5485                         &dialog_window);
5486
5487       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5488
5489       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5490       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5491
5492       button = gtk_button_new_with_label ("OK");
5493       gtk_widget_set_can_default (button, TRUE);
5494       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5495       gtk_widget_grab_default (button);
5496       gtk_widget_show (button);
5497
5498       button = gtk_button_new_with_label ("Toggle");
5499       g_signal_connect (button, "clicked",
5500                         G_CALLBACK (label_toggle),
5501                         &label);
5502       gtk_widget_set_can_default (button, TRUE);
5503       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5504       gtk_widget_show (button);
5505
5506       label = NULL;
5507     }
5508
5509   if (!gtk_widget_get_visible (dialog_window))
5510     gtk_widget_show (dialog_window);
5511   else
5512     gtk_widget_destroy (dialog_window);
5513 }
5514
5515 /* Display & Screen test 
5516  */
5517
5518 typedef struct
5519 {
5520   GtkWidget *combo;
5521   GtkWidget *entry;
5522   GtkWidget *radio_dpy;
5523   GtkWidget *toplevel;
5524   GtkWidget *dialog_window;
5525 } ScreenDisplaySelection;
5526
5527 static void
5528 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
5529 {
5530   const gchar *display_name;
5531   GdkDisplay *display = gtk_widget_get_display (widget);
5532   GtkWidget *dialog;
5533   GdkScreen *new_screen = NULL;
5534   GdkScreen *current_screen = gtk_widget_get_screen (widget);
5535   
5536   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
5537     {
5538       display_name = gtk_entry_get_text (GTK_ENTRY (data->entry));
5539       display = gdk_display_open (display_name);
5540       
5541       if (!display)
5542         {
5543           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
5544                                            GTK_DIALOG_DESTROY_WITH_PARENT,
5545                                            GTK_MESSAGE_ERROR,
5546                                            GTK_BUTTONS_OK,
5547                                            "The display :\n%s\ncannot be opened",
5548                                            display_name);
5549           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
5550           gtk_widget_show (dialog);
5551           g_signal_connect (dialog, "response",
5552                             G_CALLBACK (gtk_widget_destroy),
5553                             NULL);
5554         }
5555       else
5556         {
5557           GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
5558           gint i = 0;
5559           GtkTreeIter iter;
5560           gboolean found = FALSE;
5561           while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
5562             {
5563               gchar *name;
5564               gtk_tree_model_get (model, &iter, 0, &name, -1);
5565               found = !g_ascii_strcasecmp (display_name, name);
5566               g_free (name);
5567
5568               if (found)
5569                 break;
5570             }
5571           if (!found)
5572             gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (data->combo), display_name);
5573           new_screen = gdk_display_get_default_screen (display);
5574         }
5575     }
5576   else
5577     {
5578       gint number_of_screens = gdk_display_get_n_screens (display);
5579       gint screen_num = gdk_screen_get_number (current_screen);
5580       if ((screen_num +1) < number_of_screens)
5581         new_screen = gdk_display_get_screen (display, screen_num + 1);
5582       else
5583         new_screen = gdk_display_get_screen (display, 0);
5584     }
5585   
5586   if (new_screen) 
5587     {
5588       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
5589       gtk_widget_destroy (data->dialog_window);
5590     }
5591 }
5592
5593 void
5594 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
5595 {
5596   gtk_widget_destroy (data);
5597 }
5598
5599 void
5600 create_display_screen (GtkWidget *widget)
5601 {
5602   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
5603   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
5604   GtkWidget *bbox;
5605   ScreenDisplaySelection *scr_dpy_data;
5606   GdkScreen *screen = gtk_widget_get_screen (widget);
5607   GdkDisplay *display = gdk_screen_get_display (screen);
5608
5609   window = g_object_new (gtk_window_get_type (),
5610                            "screen", screen,
5611                            "user_data", NULL,
5612                            "type", GTK_WINDOW_TOPLEVEL,
5613                            "title",
5614                            "Screen or Display selection",
5615                            "border_width", 10, NULL);
5616   g_signal_connect (window, "destroy", 
5617                     G_CALLBACK (gtk_widget_destroy), NULL);
5618
5619   vbox = gtk_vbox_new (FALSE, 3);
5620   gtk_container_add (GTK_CONTAINER (window), vbox);
5621   
5622   frame = gtk_frame_new ("Select screen or display");
5623   gtk_container_add (GTK_CONTAINER (vbox), frame);
5624   
5625   table = gtk_table_new (2, 2, TRUE);
5626   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
5627   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
5628
5629   gtk_container_add (GTK_CONTAINER (frame), table);
5630
5631   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
5632   if (gdk_display_get_n_screens(display) > 1)
5633     radio_scr = gtk_radio_button_new_with_label 
5634     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
5635   else
5636     {    
5637       radio_scr = gtk_radio_button_new_with_label 
5638         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
5639          "only one screen on the current display");
5640       gtk_widget_set_sensitive (radio_scr, FALSE);
5641     }
5642   combo_dpy = gtk_combo_box_text_new_with_entry ();
5643   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_dpy), "diabolo:0.0");
5644   gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_dpy))),
5645                       "<hostname>:<X Server Num>.<Screen Num>");
5646
5647   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
5648   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
5649   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
5650
5651   bbox = gtk_hbutton_box_new ();
5652   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
5653   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
5654   
5655   gtk_container_add (GTK_CONTAINER (vbox), bbox);
5656
5657   gtk_container_add (GTK_CONTAINER (bbox), applyb);
5658   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
5659
5660   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
5661
5662   scr_dpy_data->entry = gtk_bin_get_child (GTK_BIN (combo_dpy));
5663   scr_dpy_data->radio_dpy = radio_dpy;
5664   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
5665   scr_dpy_data->dialog_window = window;
5666
5667   g_signal_connect (cancelb, "clicked", 
5668                     G_CALLBACK (screen_display_destroy_diag), window);
5669   g_signal_connect (applyb, "clicked", 
5670                     G_CALLBACK (screen_display_check), scr_dpy_data);
5671   gtk_widget_show_all (window);
5672 }
5673
5674 /* Event Watcher
5675  */
5676 static gboolean event_watcher_enter_id = 0;
5677 static gboolean event_watcher_leave_id = 0;
5678
5679 static gboolean
5680 event_watcher (GSignalInvocationHint *ihint,
5681                guint                  n_param_values,
5682                const GValue          *param_values,
5683                gpointer               data)
5684 {
5685   g_print ("Watch: \"%s\" emitted for %s\n",
5686            g_signal_name (ihint->signal_id),
5687            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
5688
5689   return TRUE;
5690 }
5691
5692 static void
5693 event_watcher_down (void)
5694 {
5695   if (event_watcher_enter_id)
5696     {
5697       guint signal_id;
5698
5699       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5700       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5701       event_watcher_enter_id = 0;
5702       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5703       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5704       event_watcher_leave_id = 0;
5705     }
5706 }
5707
5708 static void
5709 event_watcher_toggle (void)
5710 {
5711   if (event_watcher_enter_id)
5712     event_watcher_down ();
5713   else
5714     {
5715       guint signal_id;
5716
5717       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5718       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5719       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5720       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5721     }
5722 }
5723
5724 static void
5725 create_event_watcher (GtkWidget *widget)
5726 {
5727   GtkWidget *action_area, *content_area;
5728   GtkWidget *button;
5729
5730   if (!dialog_window)
5731     {
5732       dialog_window = gtk_dialog_new ();
5733       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5734                              gtk_widget_get_screen (widget));
5735
5736       g_signal_connect (dialog_window, "destroy",
5737                         G_CALLBACK (gtk_widget_destroyed),
5738                         &dialog_window);
5739       g_signal_connect (dialog_window, "destroy",
5740                         G_CALLBACK (event_watcher_down),
5741                         NULL);
5742
5743       content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5744       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5745
5746       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5747       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5748       gtk_widget_set_size_request (dialog_window, 200, 110);
5749
5750       button = gtk_toggle_button_new_with_label ("Activate Watch");
5751       g_signal_connect (button, "clicked",
5752                         G_CALLBACK (event_watcher_toggle),
5753                         NULL);
5754       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5755       gtk_box_pack_start (GTK_BOX (content_area), button, TRUE, TRUE, 0);
5756       gtk_widget_show (button);
5757
5758       button = gtk_button_new_with_label ("Close");
5759       g_signal_connect_swapped (button, "clicked",
5760                                 G_CALLBACK (gtk_widget_destroy),
5761                                 dialog_window);
5762       gtk_widget_set_can_default (button, TRUE);
5763       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5764       gtk_widget_grab_default (button);
5765       gtk_widget_show (button);
5766     }
5767
5768   if (!gtk_widget_get_visible (dialog_window))
5769     gtk_widget_show (dialog_window);
5770   else
5771     gtk_widget_destroy (dialog_window);
5772 }
5773
5774 /*
5775  * GtkRange
5776  */
5777
5778 static gchar*
5779 reformat_value (GtkScale *scale,
5780                 gdouble   value)
5781 {
5782   return g_strdup_printf ("-->%0.*g<--",
5783                           gtk_scale_get_digits (scale), value);
5784 }
5785
5786 static void
5787 create_range_controls (GtkWidget *widget)
5788 {
5789   static GtkWidget *window = NULL;
5790   GtkWidget *box1;
5791   GtkWidget *box2;
5792   GtkWidget *button;
5793   GtkWidget *scrollbar;
5794   GtkWidget *scale;
5795   GtkWidget *separator;
5796   GtkAdjustment *adjustment;
5797   GtkWidget *hbox;
5798
5799   if (!window)
5800     {
5801       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5802
5803       gtk_window_set_screen (GTK_WINDOW (window),
5804                              gtk_widget_get_screen (widget));
5805
5806       g_signal_connect (window, "destroy",
5807                         G_CALLBACK (gtk_widget_destroyed),
5808                         &window);
5809
5810       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5811       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5812
5813
5814       box1 = gtk_vbox_new (FALSE, 0);
5815       gtk_container_add (GTK_CONTAINER (window), box1);
5816       gtk_widget_show (box1);
5817
5818
5819       box2 = gtk_vbox_new (FALSE, 10);
5820       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5821       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5822       gtk_widget_show (box2);
5823
5824
5825       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5826
5827       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
5828       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
5829       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
5830       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5831       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5832       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5833       gtk_widget_show (scale);
5834
5835       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
5836       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
5837                                    GTK_UPDATE_CONTINUOUS);
5838       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5839       gtk_widget_show (scrollbar);
5840
5841       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
5842       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5843       g_signal_connect (scale,
5844                         "format_value",
5845                         G_CALLBACK (reformat_value),
5846                         NULL);
5847       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5848       gtk_widget_show (scale);
5849       
5850       hbox = gtk_hbox_new (FALSE, 0);
5851
5852       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
5853       gtk_widget_set_size_request (scale, -1, 200);
5854       gtk_scale_set_digits (GTK_SCALE (scale), 2);
5855       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5856       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5857       gtk_widget_show (scale);
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_range_set_inverted (GTK_RANGE (scale), TRUE);
5864       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5865       gtk_widget_show (scale);
5866
5867       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
5868       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5869       g_signal_connect (scale,
5870                         "format_value",
5871                         G_CALLBACK (reformat_value),
5872                         NULL);
5873       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5874       gtk_widget_show (scale);
5875
5876       
5877       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
5878       gtk_widget_show (hbox);
5879       
5880       separator = gtk_hseparator_new ();
5881       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5882       gtk_widget_show (separator);
5883
5884
5885       box2 = gtk_vbox_new (FALSE, 10);
5886       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5887       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5888       gtk_widget_show (box2);
5889
5890
5891       button = gtk_button_new_with_label ("close");
5892       g_signal_connect_swapped (button, "clicked",
5893                                 G_CALLBACK (gtk_widget_destroy),
5894                                 window);
5895       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5896       gtk_widget_set_can_default (button, TRUE);
5897       gtk_widget_grab_default (button);
5898       gtk_widget_show (button);
5899     }
5900
5901   if (!gtk_widget_get_visible (window))
5902     gtk_widget_show (window);
5903   else
5904     gtk_widget_destroy (window);
5905 }
5906
5907 /*
5908  * GtkRulers
5909  */
5910
5911 void
5912 create_rulers (GtkWidget *widget)
5913 {
5914   static GtkWidget *window = NULL;
5915   GtkWidget *table;
5916   GtkWidget *ruler;
5917
5918   if (!window)
5919     {
5920       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5921
5922       gtk_window_set_screen (GTK_WINDOW (window),
5923                              gtk_widget_get_screen (widget));
5924
5925       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
5926
5927       g_signal_connect (window, "destroy",
5928                         G_CALLBACK (gtk_widget_destroyed),
5929                         &window);
5930
5931       gtk_window_set_title (GTK_WINDOW (window), "rulers");
5932       gtk_widget_set_size_request (window, 300, 300);
5933       gtk_widget_set_events (window, 
5934                              GDK_POINTER_MOTION_MASK 
5935                              | GDK_POINTER_MOTION_HINT_MASK);
5936       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5937
5938       table = gtk_table_new (2, 2, FALSE);
5939       gtk_container_add (GTK_CONTAINER (window), table);
5940       gtk_widget_show (table);
5941
5942       ruler = gtk_hruler_new ();
5943       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
5944       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
5945
5946       g_signal_connect_swapped (window, 
5947                                 "motion_notify_event",
5948                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
5949                                 ruler);
5950       
5951       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
5952                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
5953       gtk_widget_show (ruler);
5954
5955
5956       ruler = gtk_vruler_new ();
5957       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
5958
5959       g_signal_connect_swapped (window, 
5960                                 "motion_notify_event",
5961                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
5962                                 ruler);
5963       
5964       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
5965                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
5966       gtk_widget_show (ruler);
5967     }
5968
5969   if (!gtk_widget_get_visible (window))
5970     gtk_widget_show (window);
5971   else
5972     gtk_widget_destroy (window);
5973 }
5974
5975 struct {
5976   GdkColor color;
5977   gchar *name;
5978 } text_colors[] = {
5979  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5980  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5981  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5982  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5983  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
5984  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5985  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5986  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5987 };
5988
5989 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5990
5991 /*
5992  * GtkNotebook
5993  */
5994
5995 static const char * book_open_xpm[] = {
5996 "16 16 4 1",
5997 "       c None s None",
5998 ".      c black",
5999 "X      c #808080",
6000 "o      c white",
6001 "                ",
6002 "  ..            ",
6003 " .Xo.    ...    ",
6004 " .Xoo. ..oo.    ",
6005 " .Xooo.Xooo...  ",
6006 " .Xooo.oooo.X.  ",
6007 " .Xooo.Xooo.X.  ",
6008 " .Xooo.oooo.X.  ",
6009 " .Xooo.Xooo.X.  ",
6010 " .Xooo.oooo.X.  ",
6011 "  .Xoo.Xoo..X.  ",
6012 "   .Xo.o..ooX.  ",
6013 "    .X..XXXXX.  ",
6014 "    ..X.......  ",
6015 "     ..         ",
6016 "                "};
6017
6018 static const char * book_closed_xpm[] = {
6019 "16 16 6 1",
6020 "       c None s None",
6021 ".      c black",
6022 "X      c red",
6023 "o      c yellow",
6024 "O      c #808080",
6025 "#      c white",
6026 "                ",
6027 "       ..       ",
6028 "     ..XX.      ",
6029 "   ..XXXXX.     ",
6030 " ..XXXXXXXX.    ",
6031 ".ooXXXXXXXXX.   ",
6032 "..ooXXXXXXXXX.  ",
6033 ".X.ooXXXXXXXXX. ",
6034 ".XX.ooXXXXXX..  ",
6035 " .XX.ooXXX..#O  ",
6036 "  .XX.oo..##OO. ",
6037 "   .XX..##OO..  ",
6038 "    .X.#OO..    ",
6039 "     ..O..      ",
6040 "      ..        ",
6041 "                "};
6042
6043 GdkPixbuf *book_open;
6044 GdkPixbuf *book_closed;
6045 GtkWidget *sample_notebook;
6046
6047 static void
6048 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
6049 {
6050   GtkWidget *page_widget;
6051   GtkWidget *pixwid;
6052
6053   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
6054
6055   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
6056   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6057   
6058   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
6059   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6060 }
6061
6062 static void
6063 page_switch (GtkWidget *widget, gpointer *page, gint page_num)
6064 {
6065   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
6066   gint old_page_num = gtk_notebook_get_current_page (notebook);
6067  
6068   if (page_num == old_page_num)
6069     return;
6070
6071   set_page_image (notebook, page_num, book_open);
6072
6073   if (old_page_num != -1)
6074     set_page_image (notebook, old_page_num, book_closed);
6075 }
6076
6077 static void
6078 tab_fill (GtkToggleButton *button, GtkWidget *child)
6079 {
6080   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6081                            "tab-fill", gtk_toggle_button_get_active (button),
6082                            NULL);
6083 }
6084
6085 static void
6086 tab_expand (GtkToggleButton *button, GtkWidget *child)
6087 {
6088   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6089                            "tab-expand", gtk_toggle_button_get_active (button),
6090                            NULL);
6091 }
6092
6093 static void
6094 create_pages (GtkNotebook *notebook, gint start, gint end)
6095 {
6096   GtkWidget *child = NULL;
6097   GtkWidget *button;
6098   GtkWidget *label;
6099   GtkWidget *hbox;
6100   GtkWidget *vbox;
6101   GtkWidget *label_box;
6102   GtkWidget *menu_box;
6103   GtkWidget *pixwid;
6104   gint i;
6105   char buffer[32];
6106   char accel_buffer[32];
6107
6108   for (i = start; i <= end; i++)
6109     {
6110       sprintf (buffer, "Page %d", i);
6111       sprintf (accel_buffer, "Page _%d", i);
6112
6113       child = gtk_frame_new (buffer);
6114       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
6115
6116       vbox = gtk_vbox_new (TRUE,0);
6117       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
6118       gtk_container_add (GTK_CONTAINER (child), vbox);
6119
6120       hbox = gtk_hbox_new (TRUE,0);
6121       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
6122
6123       button = gtk_check_button_new_with_label ("Fill Tab");
6124       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6125       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
6126       g_signal_connect (button, "toggled",
6127                         G_CALLBACK (tab_fill), child);
6128
6129       button = gtk_check_button_new_with_label ("Expand Tab");
6130       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6131       g_signal_connect (button, "toggled",
6132                         G_CALLBACK (tab_expand), child);
6133
6134       button = gtk_button_new_with_label ("Hide Page");
6135       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
6136       g_signal_connect_swapped (button, "clicked",
6137                                 G_CALLBACK (gtk_widget_hide),
6138                                 child);
6139
6140       gtk_widget_show_all (child);
6141
6142       label_box = gtk_hbox_new (FALSE, 0);
6143       pixwid = gtk_image_new_from_pixbuf (book_closed);
6144       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
6145                            
6146       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
6147       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
6148       label = gtk_label_new_with_mnemonic (accel_buffer);
6149       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
6150       gtk_widget_show_all (label_box);
6151       
6152                                        
6153       menu_box = gtk_hbox_new (FALSE, 0);
6154       pixwid = gtk_image_new_from_pixbuf (book_closed);
6155       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
6156       
6157       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
6158       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
6159       label = gtk_label_new (buffer);
6160       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
6161       gtk_widget_show_all (menu_box);
6162
6163       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
6164     }
6165 }
6166
6167 static void
6168 rotate_notebook (GtkButton   *button,
6169                  GtkNotebook *notebook)
6170 {
6171   gtk_notebook_set_tab_pos (notebook, (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
6172 }
6173
6174 static void
6175 show_all_pages (GtkButton   *button,
6176                 GtkNotebook *notebook)
6177 {  
6178   gtk_container_foreach (GTK_CONTAINER (notebook),
6179                          (GtkCallback) gtk_widget_show, NULL);
6180 }
6181
6182 static void
6183 notebook_type_changed (GtkWidget *optionmenu,
6184                        gpointer   data)
6185 {
6186   GtkNotebook *notebook;
6187   gint i, c;
6188
6189   enum {
6190     STANDARD,
6191     NOTABS,
6192     BORDERLESS,
6193     SCROLLABLE
6194   };
6195
6196   notebook = GTK_NOTEBOOK (data);
6197
6198   c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
6199
6200   switch (c)
6201     {
6202     case STANDARD:
6203       /* standard notebook */
6204       gtk_notebook_set_show_tabs (notebook, TRUE);
6205       gtk_notebook_set_show_border (notebook, TRUE);
6206       gtk_notebook_set_scrollable (notebook, FALSE);
6207       break;
6208
6209     case NOTABS:
6210       /* notabs notebook */
6211       gtk_notebook_set_show_tabs (notebook, FALSE);
6212       gtk_notebook_set_show_border (notebook, TRUE);
6213       break;
6214
6215     case BORDERLESS:
6216       /* borderless */
6217       gtk_notebook_set_show_tabs (notebook, FALSE);
6218       gtk_notebook_set_show_border (notebook, FALSE);
6219       break;
6220
6221     case SCROLLABLE:  
6222       /* scrollable */
6223       gtk_notebook_set_show_tabs (notebook, TRUE);
6224       gtk_notebook_set_show_border (notebook, TRUE);
6225       gtk_notebook_set_scrollable (notebook, TRUE);
6226       if (gtk_notebook_get_n_pages (notebook) == 5)
6227         create_pages (notebook, 6, 15);
6228
6229       return;
6230       break;
6231     }
6232
6233   if (gtk_notebook_get_n_pages (notebook) == 15)
6234     for (i = 0; i < 10; i++)
6235       gtk_notebook_remove_page (notebook, 5);
6236 }
6237
6238 static void
6239 notebook_popup (GtkToggleButton *button,
6240                 GtkNotebook     *notebook)
6241 {
6242   if (button->active)
6243     gtk_notebook_popup_enable (notebook);
6244   else
6245     gtk_notebook_popup_disable (notebook);
6246 }
6247
6248 static void
6249 create_notebook (GtkWidget *widget)
6250 {
6251   static GtkWidget *window = NULL;
6252   GtkWidget *box1;
6253   GtkWidget *box2;
6254   GtkWidget *button;
6255   GtkWidget *separator;
6256   GtkWidget *omenu;
6257   GtkWidget *label;
6258
6259   static gchar *items[] =
6260   {
6261     "Standard",
6262     "No tabs",
6263     "Borderless",
6264     "Scrollable"
6265   };
6266   
6267   if (!window)
6268     {
6269       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6270       gtk_window_set_screen (GTK_WINDOW (window),
6271                              gtk_widget_get_screen (widget));
6272
6273       g_signal_connect (window, "destroy",
6274                         G_CALLBACK (gtk_widget_destroyed),
6275                         &window);
6276
6277       gtk_window_set_title (GTK_WINDOW (window), "notebook");
6278       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6279
6280       box1 = gtk_vbox_new (FALSE, 0);
6281       gtk_container_add (GTK_CONTAINER (window), box1);
6282
6283       sample_notebook = gtk_notebook_new ();
6284       g_signal_connect (sample_notebook, "switch_page",
6285                         G_CALLBACK (page_switch), NULL);
6286       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6287       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6288       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6289
6290       gtk_widget_realize (sample_notebook);
6291
6292       if (!book_open)
6293         book_open = gdk_pixbuf_new_from_xpm_data (book_open_xpm);
6294                                                   
6295       if (!book_closed)
6296         book_closed = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
6297
6298       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6299
6300       separator = gtk_hseparator_new ();
6301       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6302       
6303       box2 = gtk_hbox_new (FALSE, 5);
6304       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6305       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6306
6307       button = gtk_check_button_new_with_label ("popup menu");
6308       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6309       g_signal_connect (button, "clicked",
6310                         G_CALLBACK (notebook_popup),
6311                         sample_notebook);
6312
6313       box2 = gtk_hbox_new (FALSE, 5);
6314       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6315       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6316
6317       label = gtk_label_new ("Notebook Style :");
6318       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6319
6320       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
6321                                  notebook_type_changed,
6322                                  sample_notebook);
6323       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6324
6325       button = gtk_button_new_with_label ("Show all Pages");
6326       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6327       g_signal_connect (button, "clicked",
6328                         G_CALLBACK (show_all_pages), sample_notebook);
6329
6330       box2 = gtk_hbox_new (TRUE, 10);
6331       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6332       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6333
6334       button = gtk_button_new_with_label ("prev");
6335       g_signal_connect_swapped (button, "clicked",
6336                                 G_CALLBACK (gtk_notebook_prev_page),
6337                                 sample_notebook);
6338       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6339
6340       button = gtk_button_new_with_label ("next");
6341       g_signal_connect_swapped (button, "clicked",
6342                                 G_CALLBACK (gtk_notebook_next_page),
6343                                 sample_notebook);
6344       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6345
6346       button = gtk_button_new_with_label ("rotate");
6347       g_signal_connect (button, "clicked",
6348                         G_CALLBACK (rotate_notebook), sample_notebook);
6349       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6350
6351       separator = gtk_hseparator_new ();
6352       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6353
6354       button = gtk_button_new_with_label ("close");
6355       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6356       g_signal_connect_swapped (button, "clicked",
6357                                 G_CALLBACK (gtk_widget_destroy),
6358                                 window);
6359       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6360       gtk_widget_set_can_default (button, TRUE);
6361       gtk_widget_grab_default (button);
6362     }
6363
6364   if (!gtk_widget_get_visible (window))
6365     gtk_widget_show_all (window);
6366   else
6367     gtk_widget_destroy (window);
6368 }
6369
6370 /*
6371  * GtkPanes
6372  */
6373
6374 void
6375 toggle_resize (GtkWidget *widget, GtkWidget *child)
6376 {
6377   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6378   GValue value = { 0, };
6379   g_value_init (&value, G_TYPE_BOOLEAN);
6380   gtk_container_child_get_property (container, child, "resize", &value);
6381   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6382   gtk_container_child_set_property (container, child, "resize", &value);
6383 }
6384
6385 void
6386 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6387 {
6388   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6389   GValue value = { 0, };
6390   g_value_init (&value, G_TYPE_BOOLEAN);
6391   gtk_container_child_get_property (container, child, "shrink", &value);
6392   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6393   gtk_container_child_set_property (container, child, "shrink", &value);
6394 }
6395
6396 static void
6397 paned_props_clicked (GtkWidget *button,
6398                      GObject   *paned)
6399 {
6400   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
6401   
6402   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
6403 }
6404
6405 GtkWidget *
6406 create_pane_options (GtkPaned    *paned,
6407                      const gchar *frame_label,
6408                      const gchar *label1,
6409                      const gchar *label2)
6410 {
6411   GtkWidget *child1, *child2;
6412   GtkWidget *frame;
6413   GtkWidget *table;
6414   GtkWidget *label;
6415   GtkWidget *button;
6416   GtkWidget *check_button;
6417
6418   child1 = gtk_paned_get_child1 (paned);
6419   child2 = gtk_paned_get_child2 (paned);
6420
6421   frame = gtk_frame_new (frame_label);
6422   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6423   
6424   table = gtk_table_new (4, 2, 4);
6425   gtk_container_add (GTK_CONTAINER (frame), table);
6426   
6427   label = gtk_label_new (label1);
6428   gtk_table_attach_defaults (GTK_TABLE (table), label,
6429                              0, 1, 0, 1);
6430   
6431   check_button = gtk_check_button_new_with_label ("Resize");
6432   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6433                              0, 1, 1, 2);
6434   g_signal_connect (check_button, "toggled",
6435                     G_CALLBACK (toggle_resize),
6436                     child1);
6437
6438   check_button = gtk_check_button_new_with_label ("Shrink");
6439   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6440                              0, 1, 2, 3);
6441   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6442                                TRUE);
6443   g_signal_connect (check_button, "toggled",
6444                     G_CALLBACK (toggle_shrink),
6445                     child1);
6446
6447   label = gtk_label_new (label2);
6448   gtk_table_attach_defaults (GTK_TABLE (table), label,
6449                              1, 2, 0, 1);
6450   
6451   check_button = gtk_check_button_new_with_label ("Resize");
6452   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6453                              1, 2, 1, 2);
6454   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6455                                TRUE);
6456   g_signal_connect (check_button, "toggled",
6457                     G_CALLBACK (toggle_resize),
6458                     child2);
6459
6460   check_button = gtk_check_button_new_with_label ("Shrink");
6461   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6462                              1, 2, 2, 3);
6463   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6464                                TRUE);
6465   g_signal_connect (check_button, "toggled",
6466                     G_CALLBACK (toggle_shrink),
6467                     child2);
6468
6469   button = gtk_button_new_with_mnemonic ("_Properties");
6470   gtk_table_attach_defaults (GTK_TABLE (table), button,
6471                              0, 2, 3, 4);
6472   g_signal_connect (button, "clicked",
6473                     G_CALLBACK (paned_props_clicked),
6474                     paned);
6475
6476   return frame;
6477 }
6478
6479 void
6480 create_panes (GtkWidget *widget)
6481 {
6482   static GtkWidget *window = NULL;
6483   GtkWidget *frame;
6484   GtkWidget *hpaned;
6485   GtkWidget *vpaned;
6486   GtkWidget *button;
6487   GtkWidget *vbox;
6488
6489   if (!window)
6490     {
6491       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6492
6493       gtk_window_set_screen (GTK_WINDOW (window),
6494                              gtk_widget_get_screen (widget));
6495       
6496       g_signal_connect (window, "destroy",
6497                         G_CALLBACK (gtk_widget_destroyed),
6498                         &window);
6499
6500       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6501       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6502
6503       vbox = gtk_vbox_new (FALSE, 0);
6504       gtk_container_add (GTK_CONTAINER (window), vbox);
6505       
6506       vpaned = gtk_vpaned_new ();
6507       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6508       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6509
6510       hpaned = gtk_hpaned_new ();
6511       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6512
6513       frame = gtk_frame_new (NULL);
6514       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6515       gtk_widget_set_size_request (frame, 60, 60);
6516       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6517       
6518       button = gtk_button_new_with_label ("Hi there");
6519       gtk_container_add (GTK_CONTAINER(frame), button);
6520
6521       frame = gtk_frame_new (NULL);
6522       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6523       gtk_widget_set_size_request (frame, 80, 60);
6524       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6525
6526       frame = gtk_frame_new (NULL);
6527       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6528       gtk_widget_set_size_request (frame, 60, 80);
6529       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6530
6531       /* Now create toggle buttons to control sizing */
6532
6533       gtk_box_pack_start (GTK_BOX (vbox),
6534                           create_pane_options (GTK_PANED (hpaned),
6535                                                "Horizontal",
6536                                                "Left",
6537                                                "Right"),
6538                           FALSE, FALSE, 0);
6539
6540       gtk_box_pack_start (GTK_BOX (vbox),
6541                           create_pane_options (GTK_PANED (vpaned),
6542                                                "Vertical",
6543                                                "Top",
6544                                                "Bottom"),
6545                           FALSE, FALSE, 0);
6546
6547       gtk_widget_show_all (vbox);
6548     }
6549
6550   if (!gtk_widget_get_visible (window))
6551     gtk_widget_show (window);
6552   else
6553     gtk_widget_destroy (window);
6554 }
6555
6556 /*
6557  * Paned keyboard navigation
6558  */
6559
6560 static GtkWidget*
6561 paned_keyboard_window1 (GtkWidget *widget)
6562 {
6563   GtkWidget *window1;
6564   GtkWidget *hpaned1;
6565   GtkWidget *frame1;
6566   GtkWidget *vbox1;
6567   GtkWidget *button7;
6568   GtkWidget *button8;
6569   GtkWidget *button9;
6570   GtkWidget *vpaned1;
6571   GtkWidget *frame2;
6572   GtkWidget *frame5;
6573   GtkWidget *hbox1;
6574   GtkWidget *button5;
6575   GtkWidget *button6;
6576   GtkWidget *frame3;
6577   GtkWidget *frame4;
6578   GtkWidget *table1;
6579   GtkWidget *button1;
6580   GtkWidget *button2;
6581   GtkWidget *button3;
6582   GtkWidget *button4;
6583
6584   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6585   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
6586   gtk_window_set_screen (GTK_WINDOW (window1), 
6587                          gtk_widget_get_screen (widget));
6588
6589   hpaned1 = gtk_hpaned_new ();
6590   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
6591
6592   frame1 = gtk_frame_new (NULL);
6593   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
6594   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
6595
6596   vbox1 = gtk_vbox_new (FALSE, 0);
6597   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
6598
6599   button7 = gtk_button_new_with_label ("button7");
6600   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
6601
6602   button8 = gtk_button_new_with_label ("button8");
6603   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
6604
6605   button9 = gtk_button_new_with_label ("button9");
6606   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
6607
6608   vpaned1 = gtk_vpaned_new ();
6609   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
6610
6611   frame2 = gtk_frame_new (NULL);
6612   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
6613   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
6614
6615   frame5 = gtk_frame_new (NULL);
6616   gtk_container_add (GTK_CONTAINER (frame2), frame5);
6617
6618   hbox1 = gtk_hbox_new (FALSE, 0);
6619   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
6620
6621   button5 = gtk_button_new_with_label ("button5");
6622   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
6623
6624   button6 = gtk_button_new_with_label ("button6");
6625   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
6626
6627   frame3 = gtk_frame_new (NULL);
6628   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
6629   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
6630
6631   frame4 = gtk_frame_new ("Buttons");
6632   gtk_container_add (GTK_CONTAINER (frame3), frame4);
6633   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
6634
6635   table1 = gtk_table_new (2, 2, FALSE);
6636   gtk_container_add (GTK_CONTAINER (frame4), table1);
6637   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
6638
6639   button1 = gtk_button_new_with_label ("button1");
6640   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
6641                     (GtkAttachOptions) (GTK_FILL),
6642                     (GtkAttachOptions) (0), 0, 0);
6643
6644   button2 = gtk_button_new_with_label ("button2");
6645   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
6646                     (GtkAttachOptions) (GTK_FILL),
6647                     (GtkAttachOptions) (0), 0, 0);
6648
6649   button3 = gtk_button_new_with_label ("button3");
6650   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
6651                     (GtkAttachOptions) (GTK_FILL),
6652                     (GtkAttachOptions) (0), 0, 0);
6653
6654   button4 = gtk_button_new_with_label ("button4");
6655   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
6656                     (GtkAttachOptions) (GTK_FILL),
6657                     (GtkAttachOptions) (0), 0, 0);
6658
6659   return window1;
6660 }
6661
6662 static GtkWidget*
6663 paned_keyboard_window2 (GtkWidget *widget)
6664 {
6665   GtkWidget *window2;
6666   GtkWidget *hpaned2;
6667   GtkWidget *frame6;
6668   GtkWidget *button13;
6669   GtkWidget *hbox2;
6670   GtkWidget *vpaned2;
6671   GtkWidget *frame7;
6672   GtkWidget *button12;
6673   GtkWidget *frame8;
6674   GtkWidget *button11;
6675   GtkWidget *button10;
6676
6677   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6678   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
6679
6680   gtk_window_set_screen (GTK_WINDOW (window2), 
6681                          gtk_widget_get_screen (widget));
6682
6683   hpaned2 = gtk_hpaned_new ();
6684   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
6685
6686   frame6 = gtk_frame_new (NULL);
6687   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
6688   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
6689
6690   button13 = gtk_button_new_with_label ("button13");
6691   gtk_container_add (GTK_CONTAINER (frame6), button13);
6692
6693   hbox2 = gtk_hbox_new (FALSE, 0);
6694   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
6695
6696   vpaned2 = gtk_vpaned_new ();
6697   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
6698
6699   frame7 = gtk_frame_new (NULL);
6700   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
6701   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
6702
6703   button12 = gtk_button_new_with_label ("button12");
6704   gtk_container_add (GTK_CONTAINER (frame7), button12);
6705
6706   frame8 = gtk_frame_new (NULL);
6707   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
6708   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
6709
6710   button11 = gtk_button_new_with_label ("button11");
6711   gtk_container_add (GTK_CONTAINER (frame8), button11);
6712
6713   button10 = gtk_button_new_with_label ("button10");
6714   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
6715
6716   return window2;
6717 }
6718
6719 static GtkWidget*
6720 paned_keyboard_window3 (GtkWidget *widget)
6721 {
6722   GtkWidget *window3;
6723   GtkWidget *vbox2;
6724   GtkWidget *label1;
6725   GtkWidget *hpaned3;
6726   GtkWidget *frame9;
6727   GtkWidget *button14;
6728   GtkWidget *hpaned4;
6729   GtkWidget *frame10;
6730   GtkWidget *button15;
6731   GtkWidget *hpaned5;
6732   GtkWidget *frame11;
6733   GtkWidget *button16;
6734   GtkWidget *frame12;
6735   GtkWidget *button17;
6736
6737   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6738   g_object_set_data (G_OBJECT (window3), "window3", window3);
6739   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
6740
6741   gtk_window_set_screen (GTK_WINDOW (window3), 
6742                          gtk_widget_get_screen (widget));
6743   
6744
6745   vbox2 = gtk_vbox_new (FALSE, 0);
6746   gtk_container_add (GTK_CONTAINER (window3), vbox2);
6747
6748   label1 = gtk_label_new ("Three panes nested inside each other");
6749   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
6750
6751   hpaned3 = gtk_hpaned_new ();
6752   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
6753
6754   frame9 = gtk_frame_new (NULL);
6755   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
6756   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
6757
6758   button14 = gtk_button_new_with_label ("button14");
6759   gtk_container_add (GTK_CONTAINER (frame9), button14);
6760
6761   hpaned4 = gtk_hpaned_new ();
6762   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
6763
6764   frame10 = gtk_frame_new (NULL);
6765   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
6766   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
6767
6768   button15 = gtk_button_new_with_label ("button15");
6769   gtk_container_add (GTK_CONTAINER (frame10), button15);
6770
6771   hpaned5 = gtk_hpaned_new ();
6772   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
6773
6774   frame11 = gtk_frame_new (NULL);
6775   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
6776   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
6777
6778   button16 = gtk_button_new_with_label ("button16");
6779   gtk_container_add (GTK_CONTAINER (frame11), button16);
6780
6781   frame12 = gtk_frame_new (NULL);
6782   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
6783   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
6784
6785   button17 = gtk_button_new_with_label ("button17");
6786   gtk_container_add (GTK_CONTAINER (frame12), button17);
6787
6788   return window3;
6789 }
6790
6791 static GtkWidget*
6792 paned_keyboard_window4 (GtkWidget *widget)
6793 {
6794   GtkWidget *window4;
6795   GtkWidget *vbox3;
6796   GtkWidget *label2;
6797   GtkWidget *hpaned6;
6798   GtkWidget *vpaned3;
6799   GtkWidget *button19;
6800   GtkWidget *button18;
6801   GtkWidget *hbox3;
6802   GtkWidget *vpaned4;
6803   GtkWidget *button21;
6804   GtkWidget *button20;
6805   GtkWidget *vpaned5;
6806   GtkWidget *button23;
6807   GtkWidget *button22;
6808   GtkWidget *vpaned6;
6809   GtkWidget *button25;
6810   GtkWidget *button24;
6811
6812   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6813   g_object_set_data (G_OBJECT (window4), "window4", window4);
6814   gtk_window_set_title (GTK_WINDOW (window4), "window4");
6815
6816   gtk_window_set_screen (GTK_WINDOW (window4), 
6817                          gtk_widget_get_screen (widget));
6818
6819   vbox3 = gtk_vbox_new (FALSE, 0);
6820   gtk_container_add (GTK_CONTAINER (window4), vbox3);
6821
6822   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
6823   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
6824   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
6825
6826   hpaned6 = gtk_hpaned_new ();
6827   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
6828
6829   vpaned3 = gtk_vpaned_new ();
6830   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
6831
6832   button19 = gtk_button_new_with_label ("button19");
6833   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
6834
6835   button18 = gtk_button_new_with_label ("button18");
6836   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
6837
6838   hbox3 = gtk_hbox_new (FALSE, 0);
6839   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
6840
6841   vpaned4 = gtk_vpaned_new ();
6842   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
6843
6844   button21 = gtk_button_new_with_label ("button21");
6845   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
6846
6847   button20 = gtk_button_new_with_label ("button20");
6848   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
6849
6850   vpaned5 = gtk_vpaned_new ();
6851   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
6852
6853   button23 = gtk_button_new_with_label ("button23");
6854   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
6855
6856   button22 = gtk_button_new_with_label ("button22");
6857   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
6858
6859   vpaned6 = gtk_vpaned_new ();
6860   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
6861
6862   button25 = gtk_button_new_with_label ("button25");
6863   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
6864
6865   button24 = gtk_button_new_with_label ("button24");
6866   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
6867
6868   return window4;
6869 }
6870
6871 static void
6872 create_paned_keyboard_navigation (GtkWidget *widget)
6873 {
6874   static GtkWidget *window1 = NULL;
6875   static GtkWidget *window2 = NULL;
6876   static GtkWidget *window3 = NULL;
6877   static GtkWidget *window4 = NULL;
6878
6879   if (window1 && 
6880      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
6881     {
6882       gtk_widget_destroy (window1);
6883       gtk_widget_destroy (window2);
6884       gtk_widget_destroy (window3);
6885       gtk_widget_destroy (window4);
6886     }
6887   
6888   if (!window1)
6889     {
6890       window1 = paned_keyboard_window1 (widget);
6891       g_signal_connect (window1, "destroy",
6892                         G_CALLBACK (gtk_widget_destroyed),
6893                         &window1);
6894     }
6895
6896   if (!window2)
6897     {
6898       window2 = paned_keyboard_window2 (widget);
6899       g_signal_connect (window2, "destroy",
6900                         G_CALLBACK (gtk_widget_destroyed),
6901                         &window2);
6902     }
6903
6904   if (!window3)
6905     {
6906       window3 = paned_keyboard_window3 (widget);
6907       g_signal_connect (window3, "destroy",
6908                         G_CALLBACK (gtk_widget_destroyed),
6909                         &window3);
6910     }
6911
6912   if (!window4)
6913     {
6914       window4 = paned_keyboard_window4 (widget);
6915       g_signal_connect (window4, "destroy",
6916                         G_CALLBACK (gtk_widget_destroyed),
6917                         &window4);
6918     }
6919
6920   if (gtk_widget_get_visible (window1))
6921     gtk_widget_destroy (GTK_WIDGET (window1));
6922   else
6923     gtk_widget_show_all (GTK_WIDGET (window1));
6924
6925   if (gtk_widget_get_visible (window2))
6926     gtk_widget_destroy (GTK_WIDGET (window2));
6927   else
6928     gtk_widget_show_all (GTK_WIDGET (window2));
6929
6930   if (gtk_widget_get_visible (window3))
6931     gtk_widget_destroy (GTK_WIDGET (window3));
6932   else
6933     gtk_widget_show_all (GTK_WIDGET (window3));
6934
6935   if (gtk_widget_get_visible (window4))
6936     gtk_widget_destroy (GTK_WIDGET (window4));
6937   else
6938     gtk_widget_show_all (GTK_WIDGET (window4));
6939 }
6940
6941
6942 /*
6943  * Shaped Windows
6944  */
6945
6946 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6947
6948 static void
6949 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6950 {
6951   CursorOffset *p;
6952
6953   /* ignore double and triple click */
6954   if (event->type != GDK_BUTTON_PRESS)
6955     return;
6956
6957   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6958   p->x = (int) event->x;
6959   p->y = (int) event->y;
6960
6961   gtk_grab_add (widget);
6962   gdk_pointer_grab (gtk_widget_get_window (widget), TRUE,
6963                     GDK_BUTTON_RELEASE_MASK |
6964                     GDK_BUTTON_MOTION_MASK |
6965                     GDK_POINTER_MOTION_HINT_MASK,
6966                     NULL, NULL, 0);
6967 }
6968
6969 static void
6970 shape_released (GtkWidget *widget)
6971 {
6972   gtk_grab_remove (widget);
6973   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
6974                               GDK_CURRENT_TIME);
6975 }
6976
6977 static void
6978 shape_motion (GtkWidget      *widget, 
6979               GdkEventMotion *event)
6980 {
6981   gint xp, yp;
6982   CursorOffset * p;
6983   GdkModifierType mask;
6984
6985   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6986
6987   /*
6988    * Can't use event->x / event->y here 
6989    * because I need absolute coordinates.
6990    */
6991   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
6992   gtk_window_move (GTK_WINDOW (widget), xp  - p->x, yp  - p->y);
6993 }
6994
6995 GtkWidget *
6996 shape_create_icon (GdkScreen *screen,
6997                    char      *xpm_file,
6998                    gint       x,
6999                    gint       y,
7000                    gint       px,
7001                    gint       py,
7002                    gint       window_type)
7003 {
7004   GtkWidget *window;
7005   GtkWidget *image;
7006   GtkWidget *fixed;
7007   CursorOffset* icon_pos;
7008   cairo_surface_t *mask;
7009   cairo_region_t *mask_region;
7010   GdkPixbuf *pixbuf;
7011   cairo_t *cr;
7012
7013   /*
7014    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
7015    */
7016   window = gtk_window_new (window_type);
7017   gtk_window_set_screen (GTK_WINDOW (window), screen);
7018   
7019   fixed = gtk_fixed_new ();
7020   gtk_widget_set_size_request (fixed, 100, 100);
7021   gtk_container_add (GTK_CONTAINER (window), fixed);
7022   gtk_widget_show (fixed);
7023   
7024   gtk_widget_set_events (window, 
7025                          gtk_widget_get_events (window) |
7026                          GDK_BUTTON_MOTION_MASK |
7027                          GDK_POINTER_MOTION_HINT_MASK |
7028                          GDK_BUTTON_PRESS_MASK);
7029
7030   gtk_widget_realize (window);
7031
7032   pixbuf = gdk_pixbuf_new_from_file (xpm_file, NULL);
7033   g_assert (pixbuf); /* FIXME: error handling */
7034
7035   mask = cairo_image_surface_create (CAIRO_FORMAT_A1,
7036                                      gdk_pixbuf_get_width (pixbuf),
7037                                      gdk_pixbuf_get_height (pixbuf));
7038   cr = cairo_create (mask);
7039   gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
7040   cairo_paint (cr);
7041   cairo_destroy (cr);
7042
7043   mask_region = gdk_cairo_region_create_from_surface (mask);
7044                                                   
7045   cairo_region_translate (mask_region, px, py);
7046
7047   image = gtk_image_new_from_pixbuf (pixbuf);
7048   gtk_fixed_put (GTK_FIXED (fixed), image, px,py);
7049   gtk_widget_show (image);
7050   
7051   gtk_widget_shape_combine_region (window, mask_region);
7052   
7053   cairo_region_destroy (mask_region);
7054   cairo_surface_destroy (mask);
7055   g_object_unref (pixbuf);
7056
7057   g_signal_connect (window, "button_press_event",
7058                     G_CALLBACK (shape_pressed), NULL);
7059   g_signal_connect (window, "button_release_event",
7060                     G_CALLBACK (shape_released), NULL);
7061   g_signal_connect (window, "motion_notify_event",
7062                     G_CALLBACK (shape_motion), NULL);
7063
7064   icon_pos = g_new (CursorOffset, 1);
7065   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
7066
7067   gtk_window_move (GTK_WINDOW (window), x, y);
7068   gtk_widget_show (window);
7069   
7070   return window;
7071 }
7072
7073 void 
7074 create_shapes (GtkWidget *widget)
7075 {
7076   /* Variables used by the Drag/Drop and Shape Window demos */
7077   static GtkWidget *modeller = NULL;
7078   static GtkWidget *sheets = NULL;
7079   static GtkWidget *rings = NULL;
7080   static GtkWidget *with_region = NULL;
7081   GdkScreen *screen = gtk_widget_get_screen (widget);
7082   
7083   if (!(file_exists ("Modeller.xpm") &&
7084         file_exists ("FilesQueue.xpm") &&
7085         file_exists ("3DRings.xpm")))
7086     return;
7087   
7088
7089   if (!modeller)
7090     {
7091       modeller = shape_create_icon (screen, "Modeller.xpm",
7092                                     440, 140, 0,0, GTK_WINDOW_POPUP);
7093
7094       g_signal_connect (modeller, "destroy",
7095                         G_CALLBACK (gtk_widget_destroyed),
7096                         &modeller);
7097     }
7098   else
7099     gtk_widget_destroy (modeller);
7100
7101   if (!sheets)
7102     {
7103       sheets = shape_create_icon (screen, "FilesQueue.xpm",
7104                                   580, 170, 0,0, GTK_WINDOW_POPUP);
7105
7106       g_signal_connect (sheets, "destroy",
7107                         G_CALLBACK (gtk_widget_destroyed),
7108                         &sheets);
7109
7110     }
7111   else
7112     gtk_widget_destroy (sheets);
7113
7114   if (!rings)
7115     {
7116       rings = shape_create_icon (screen, "3DRings.xpm",
7117                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7118
7119       g_signal_connect (rings, "destroy",
7120                         G_CALLBACK (gtk_widget_destroyed),
7121                         &rings);
7122     }
7123   else
7124     gtk_widget_destroy (rings);
7125
7126   if (!with_region)
7127     {
7128       cairo_region_t *region;
7129       gint x, y;
7130       
7131       with_region = shape_create_icon (screen, "3DRings.xpm",
7132                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7133
7134       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
7135       
7136       g_signal_connect (with_region, "destroy",
7137                         G_CALLBACK (gtk_widget_destroyed),
7138                         &with_region);
7139
7140       /* reset shape from mask to a region */
7141       x = 0;
7142       y = 0;
7143       region = cairo_region_create ();
7144
7145       while (x < 460)
7146         {
7147           while (y < 270)
7148             {
7149               GdkRectangle rect;
7150               rect.x = x;
7151               rect.y = y;
7152               rect.width = 10;
7153               rect.height = 10;
7154
7155               cairo_region_union_rectangle (region, &rect);
7156               
7157               y += 20;
7158             }
7159           y = 0;
7160           x += 20;
7161         }
7162
7163       gdk_window_shape_combine_region (gtk_widget_get_window (with_region),
7164                                        region,
7165                                        0, 0);
7166     }
7167   else
7168     gtk_widget_destroy (with_region);
7169 }
7170
7171 /*
7172  * WM Hints demo
7173  */
7174
7175 void
7176 create_wmhints (GtkWidget *widget)
7177 {
7178   static GtkWidget *window = NULL;
7179   GtkWidget *label;
7180   GtkWidget *separator;
7181   GtkWidget *button;
7182   GtkWidget *box1;
7183   GtkWidget *box2;
7184   GdkWindow *gdk_window;
7185   GdkPixbuf *pixbuf;
7186   GList *list;
7187
7188   if (!window)
7189     {
7190       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7191
7192       gtk_window_set_screen (GTK_WINDOW (window),
7193                              gtk_widget_get_screen (widget));
7194       
7195       g_signal_connect (window, "destroy",
7196                         G_CALLBACK (gtk_widget_destroyed),
7197                         &window);
7198
7199       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
7200       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7201
7202       gtk_widget_realize (window);
7203
7204       gdk_window = gtk_widget_get_window (window);
7205
7206       pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
7207       list = g_list_prepend (NULL, pixbuf);
7208
7209       gdk_window_set_icon_list (gdk_window, list);
7210       
7211       g_list_free (list);
7212       g_object_unref (pixbuf);
7213
7214       gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
7215   
7216       gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL | GDK_DECOR_MENU);
7217       gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
7218       
7219       box1 = gtk_vbox_new (FALSE, 0);
7220       gtk_container_add (GTK_CONTAINER (window), box1);
7221       gtk_widget_show (box1);
7222
7223       label = gtk_label_new ("Try iconizing me!");
7224       gtk_widget_set_size_request (label, 150, 50);
7225       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
7226       gtk_widget_show (label);
7227
7228
7229       separator = gtk_hseparator_new ();
7230       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7231       gtk_widget_show (separator);
7232
7233
7234       box2 = gtk_vbox_new (FALSE, 10);
7235       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7236       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7237       gtk_widget_show (box2);
7238
7239
7240       button = gtk_button_new_with_label ("close");
7241
7242       g_signal_connect_swapped (button, "clicked",
7243                                 G_CALLBACK (gtk_widget_destroy),
7244                                 window);
7245
7246       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7247       gtk_widget_set_can_default (button, TRUE);
7248       gtk_widget_grab_default (button);
7249       gtk_widget_show (button);
7250     }
7251
7252   if (!gtk_widget_get_visible (window))
7253     gtk_widget_show (window);
7254   else
7255     gtk_widget_destroy (window);
7256 }
7257
7258
7259 /*
7260  * Window state tracking
7261  */
7262
7263 static gint
7264 window_state_callback (GtkWidget *widget,
7265                        GdkEventWindowState *event,
7266                        gpointer data)
7267 {
7268   GtkWidget *label = data;
7269   gchar *msg;
7270
7271   msg = g_strconcat (gtk_window_get_title (GTK_WINDOW (widget)), ": ",
7272                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
7273                      "withdrawn" : "not withdrawn", ", ",
7274                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
7275                      "iconified" : "not iconified", ", ",
7276                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
7277                      "sticky" : "not sticky", ", ",
7278                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
7279                      "maximized" : "not maximized", ", ",
7280                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
7281                      "fullscreen" : "not fullscreen",
7282                      (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
7283                      "above" : "not above", ", ",
7284                      (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
7285                      "below" : "not below", ", ",
7286                      NULL);
7287   
7288   gtk_label_set_text (GTK_LABEL (label), msg);
7289
7290   g_free (msg);
7291
7292   return FALSE;
7293 }
7294
7295 static GtkWidget*
7296 tracking_label (GtkWidget *window)
7297 {
7298   GtkWidget *label;
7299   GtkWidget *hbox;
7300   GtkWidget *button;
7301
7302   hbox = gtk_hbox_new (FALSE, 5);
7303
7304   g_signal_connect_object (hbox,
7305                            "destroy",
7306                            G_CALLBACK (gtk_widget_destroy),
7307                            window,
7308                            G_CONNECT_SWAPPED);
7309   
7310   label = gtk_label_new ("<no window state events received>");
7311   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
7312   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
7313   
7314   g_signal_connect (window,
7315                     "window_state_event",
7316                     G_CALLBACK (window_state_callback),
7317                     label);
7318
7319   button = gtk_button_new_with_label ("Deiconify");
7320   g_signal_connect_object (button,
7321                            "clicked",
7322                            G_CALLBACK (gtk_window_deiconify),
7323                            window,
7324                            G_CONNECT_SWAPPED);
7325   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7326
7327   button = gtk_button_new_with_label ("Iconify");
7328   g_signal_connect_object (button,
7329                            "clicked",
7330                            G_CALLBACK (gtk_window_iconify),
7331                            window,
7332                            G_CONNECT_SWAPPED);
7333   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7334
7335   button = gtk_button_new_with_label ("Fullscreen");
7336   g_signal_connect_object (button,
7337                            "clicked",
7338                            G_CALLBACK (gtk_window_fullscreen),
7339                            window,
7340                            G_CONNECT_SWAPPED);
7341   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7342
7343   button = gtk_button_new_with_label ("Unfullscreen");
7344   g_signal_connect_object (button,
7345                            "clicked",
7346                            G_CALLBACK (gtk_window_unfullscreen),
7347                            window,
7348                            G_CONNECT_SWAPPED);
7349   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7350   
7351   button = gtk_button_new_with_label ("Present");
7352   g_signal_connect_object (button,
7353                            "clicked",
7354                            G_CALLBACK (gtk_window_present),
7355                            window,
7356                            G_CONNECT_SWAPPED);
7357   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7358
7359   button = gtk_button_new_with_label ("Show");
7360   g_signal_connect_object (button,
7361                            "clicked",
7362                            G_CALLBACK (gtk_widget_show),
7363                            window,
7364                            G_CONNECT_SWAPPED);
7365   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7366   
7367   gtk_widget_show_all (hbox);
7368   
7369   return hbox;
7370 }
7371
7372 void
7373 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
7374 {
7375   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7376
7377   gtk_window_set_keep_above (GTK_WINDOW (data),
7378                              gtk_toggle_button_get_active (togglebutton));
7379
7380   if (gtk_toggle_button_get_active (togglebutton))
7381     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7382 }
7383
7384 void
7385 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
7386 {
7387   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7388
7389   gtk_window_set_keep_below (GTK_WINDOW (data),
7390                              gtk_toggle_button_get_active (togglebutton));
7391
7392   if (gtk_toggle_button_get_active (togglebutton))
7393     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7394 }
7395
7396
7397 static GtkWidget*
7398 get_state_controls (GtkWidget *window)
7399 {
7400   GtkWidget *vbox;
7401   GtkWidget *button;
7402   GtkWidget *button_above;
7403   GtkWidget *button_below;
7404
7405   vbox = gtk_vbox_new (FALSE, 0);
7406   
7407   button = gtk_button_new_with_label ("Stick");
7408   g_signal_connect_object (button,
7409                            "clicked",
7410                            G_CALLBACK (gtk_window_stick),
7411                            window,
7412                            G_CONNECT_SWAPPED);
7413   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7414
7415   button = gtk_button_new_with_label ("Unstick");
7416   g_signal_connect_object (button,
7417                            "clicked",
7418                            G_CALLBACK (gtk_window_unstick),
7419                            window,
7420                            G_CONNECT_SWAPPED);
7421   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7422   
7423   button = gtk_button_new_with_label ("Maximize");
7424   g_signal_connect_object (button,
7425                            "clicked",
7426                            G_CALLBACK (gtk_window_maximize),
7427                            window,
7428                            G_CONNECT_SWAPPED);
7429   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7430
7431   button = gtk_button_new_with_label ("Unmaximize");
7432   g_signal_connect_object (button,
7433                            "clicked",
7434                            G_CALLBACK (gtk_window_unmaximize),
7435                            window,
7436                            G_CONNECT_SWAPPED);
7437   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7438
7439   button = gtk_button_new_with_label ("Iconify");
7440   g_signal_connect_object (button,
7441                            "clicked",
7442                            G_CALLBACK (gtk_window_iconify),
7443                            window,
7444                            G_CONNECT_SWAPPED);
7445   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7446
7447   button = gtk_button_new_with_label ("Fullscreen");
7448   g_signal_connect_object (button,
7449                            "clicked",
7450                            G_CALLBACK (gtk_window_fullscreen),
7451                            window,
7452                            G_CONNECT_SWAPPED);
7453   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7454
7455   button = gtk_button_new_with_label ("Unfullscreen");
7456   g_signal_connect_object (button,
7457                            "clicked",
7458                            G_CALLBACK (gtk_window_unfullscreen),
7459                            window,
7460                            G_CONNECT_SWAPPED);
7461   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7462
7463   button_above = gtk_toggle_button_new_with_label ("Keep above");
7464   g_signal_connect (button_above,
7465                     "toggled",
7466                     G_CALLBACK (keep_window_above),
7467                     window);
7468   gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
7469
7470   button_below = gtk_toggle_button_new_with_label ("Keep below");
7471   g_signal_connect (button_below,
7472                     "toggled",
7473                     G_CALLBACK (keep_window_below),
7474                     window);
7475   gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
7476
7477   g_object_set_data (G_OBJECT (button_above), "radio", button_below);
7478   g_object_set_data (G_OBJECT (button_below), "radio", button_above);
7479
7480   button = gtk_button_new_with_label ("Hide (withdraw)");
7481   g_signal_connect_object (button,
7482                            "clicked",
7483                            G_CALLBACK (gtk_widget_hide),
7484                            window,
7485                            G_CONNECT_SWAPPED);
7486   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7487   
7488   gtk_widget_show_all (vbox);
7489
7490   return vbox;
7491 }
7492
7493 void
7494 create_window_states (GtkWidget *widget)
7495 {
7496   static GtkWidget *window = NULL;
7497   GtkWidget *label;
7498   GtkWidget *box1;
7499   GtkWidget *iconified;
7500   GtkWidget *normal;
7501   GtkWidget *controls;
7502
7503   if (!window)
7504     {
7505       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7506       gtk_window_set_screen (GTK_WINDOW (window),
7507                              gtk_widget_get_screen (widget));
7508
7509       g_signal_connect (window, "destroy",
7510                         G_CALLBACK (gtk_widget_destroyed),
7511                         &window);
7512
7513       gtk_window_set_title (GTK_WINDOW (window), "Window states");
7514       
7515       box1 = gtk_vbox_new (FALSE, 0);
7516       gtk_container_add (GTK_CONTAINER (window), box1);
7517
7518       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7519
7520       gtk_window_set_screen (GTK_WINDOW (iconified),
7521                              gtk_widget_get_screen (widget));
7522       
7523       g_signal_connect_object (iconified, "destroy",
7524                                G_CALLBACK (gtk_widget_destroy),
7525                                window,
7526                                G_CONNECT_SWAPPED);
7527       gtk_window_iconify (GTK_WINDOW (iconified));
7528       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
7529       controls = get_state_controls (iconified);
7530       gtk_container_add (GTK_CONTAINER (iconified), controls);
7531       
7532       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7533
7534       gtk_window_set_screen (GTK_WINDOW (normal),
7535                              gtk_widget_get_screen (widget));
7536       
7537       g_signal_connect_object (normal, "destroy",
7538                                G_CALLBACK (gtk_widget_destroy),
7539                                window,
7540                                G_CONNECT_SWAPPED);
7541       
7542       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
7543       controls = get_state_controls (normal);
7544       gtk_container_add (GTK_CONTAINER (normal), controls);
7545       
7546       label = tracking_label (iconified);
7547       gtk_container_add (GTK_CONTAINER (box1), label);
7548
7549       label = tracking_label (normal);
7550       gtk_container_add (GTK_CONTAINER (box1), label);
7551
7552       gtk_widget_show_all (iconified);
7553       gtk_widget_show_all (normal);
7554       gtk_widget_show_all (box1);
7555     }
7556
7557   if (!gtk_widget_get_visible (window))
7558     gtk_widget_show (window);
7559   else
7560     gtk_widget_destroy (window);
7561 }
7562
7563 /*
7564  * Window sizing
7565  */
7566
7567 static gint
7568 configure_event_callback (GtkWidget *widget,
7569                           GdkEventConfigure *event,
7570                           gpointer data)
7571 {
7572   GtkWidget *label = data;
7573   gchar *msg;
7574   gint x, y;
7575   
7576   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
7577   
7578   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
7579                          "position: %d, %d",
7580                          event->x, event->y, event->width, event->height,
7581                          x, y);
7582   
7583   gtk_label_set_text (GTK_LABEL (label), msg);
7584
7585   g_free (msg);
7586
7587   return FALSE;
7588 }
7589
7590 static void
7591 get_ints (GtkWidget *window,
7592           gint      *a,
7593           gint      *b)
7594 {
7595   GtkWidget *spin1;
7596   GtkWidget *spin2;
7597
7598   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
7599   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
7600
7601   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
7602   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7603 }
7604
7605 static void
7606 set_size_callback (GtkWidget *widget,
7607                    gpointer   data)
7608 {
7609   gint w, h;
7610   
7611   get_ints (data, &w, &h);
7612
7613   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
7614 }
7615
7616 static void
7617 unset_default_size_callback (GtkWidget *widget,
7618                              gpointer   data)
7619 {
7620   gtk_window_set_default_size (g_object_get_data (data, "target"),
7621                                -1, -1);
7622 }
7623
7624 static void
7625 set_default_size_callback (GtkWidget *widget,
7626                            gpointer   data)
7627 {
7628   gint w, h;
7629   
7630   get_ints (data, &w, &h);
7631
7632   gtk_window_set_default_size (g_object_get_data (data, "target"),
7633                                w, h);
7634 }
7635
7636 static void
7637 unset_size_request_callback (GtkWidget *widget,
7638                              gpointer   data)
7639 {
7640   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7641                                -1, -1);
7642 }
7643
7644 static void
7645 set_size_request_callback (GtkWidget *widget,
7646                            gpointer   data)
7647 {
7648   gint w, h;
7649   
7650   get_ints (data, &w, &h);
7651
7652   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7653                                w, h);
7654 }
7655
7656 static void
7657 set_location_callback (GtkWidget *widget,
7658                        gpointer   data)
7659 {
7660   gint x, y;
7661   
7662   get_ints (data, &x, &y);
7663
7664   gtk_window_move (g_object_get_data (data, "target"), x, y);
7665 }
7666
7667 static void
7668 move_to_position_callback (GtkWidget *widget,
7669                            gpointer   data)
7670 {
7671   gint x, y;
7672   GtkWindow *window;
7673
7674   window = g_object_get_data (data, "target");
7675   
7676   gtk_window_get_position (window, &x, &y);
7677
7678   gtk_window_move (window, x, y);
7679 }
7680
7681 static void
7682 set_geometry_callback (GtkWidget *entry,
7683                        gpointer   data)
7684 {
7685   gchar *text;
7686   GtkWindow *target;
7687
7688   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
7689   
7690   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
7691
7692   if (!gtk_window_parse_geometry (target, text))
7693     g_print ("Bad geometry string '%s'\n", text);
7694
7695   g_free (text);
7696 }
7697
7698 static void
7699 resizable_callback (GtkWidget *widget,
7700                      gpointer   data)
7701 {
7702   g_object_set (g_object_get_data (data, "target"),
7703                 "resizable", GTK_TOGGLE_BUTTON (widget)->active,
7704                 NULL);
7705 }
7706
7707 static void
7708 gravity_selected (GtkWidget *widget,
7709                   gpointer   data)
7710 {
7711   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
7712                           gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GDK_GRAVITY_NORTH_WEST);
7713 }
7714
7715 static void
7716 pos_selected (GtkWidget *widget,
7717               gpointer   data)
7718 {
7719   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
7720                            gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GTK_WIN_POS_NONE);
7721 }
7722
7723 static void
7724 move_gravity_window_to_current_position (GtkWidget *widget,
7725                                          gpointer   data)
7726 {
7727   gint x, y;
7728   GtkWindow *window;
7729
7730   window = GTK_WINDOW (data);    
7731   
7732   gtk_window_get_position (window, &x, &y);
7733
7734   gtk_window_move (window, x, y);
7735 }
7736
7737 static void
7738 get_screen_corner (GtkWindow *window,
7739                    gint      *x,
7740                    gint      *y)
7741 {
7742   int w, h;
7743   GdkScreen * screen = gtk_window_get_screen (window);
7744   
7745   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
7746
7747   switch (gtk_window_get_gravity (window))
7748     {
7749     case GDK_GRAVITY_SOUTH_EAST:
7750       *x = gdk_screen_get_width (screen) - w;
7751       *y = gdk_screen_get_height (screen) - h;
7752       break;
7753
7754     case GDK_GRAVITY_NORTH_EAST:
7755       *x = gdk_screen_get_width (screen) - w;
7756       *y = 0;
7757       break;
7758
7759     case GDK_GRAVITY_SOUTH_WEST:
7760       *x = 0;
7761       *y = gdk_screen_get_height (screen) - h;
7762       break;
7763
7764     case GDK_GRAVITY_NORTH_WEST:
7765       *x = 0;
7766       *y = 0;
7767       break;
7768       
7769     case GDK_GRAVITY_SOUTH:
7770       *x = (gdk_screen_get_width (screen) - w) / 2;
7771       *y = gdk_screen_get_height (screen) - h;
7772       break;
7773
7774     case GDK_GRAVITY_NORTH:
7775       *x = (gdk_screen_get_width (screen) - w) / 2;
7776       *y = 0;
7777       break;
7778
7779     case GDK_GRAVITY_WEST:
7780       *x = 0;
7781       *y = (gdk_screen_get_height (screen) - h) / 2;
7782       break;
7783
7784     case GDK_GRAVITY_EAST:
7785       *x = gdk_screen_get_width (screen) - w;
7786       *y = (gdk_screen_get_height (screen) - h) / 2;
7787       break;
7788
7789     case GDK_GRAVITY_CENTER:
7790       *x = (gdk_screen_get_width (screen) - w) / 2;
7791       *y = (gdk_screen_get_height (screen) - h) / 2;
7792       break;
7793
7794     case GDK_GRAVITY_STATIC:
7795       /* pick some random numbers */
7796       *x = 350;
7797       *y = 350;
7798       break;
7799
7800     default:
7801       g_assert_not_reached ();
7802       break;
7803     }
7804 }
7805
7806 static void
7807 move_gravity_window_to_starting_position (GtkWidget *widget,
7808                                           gpointer   data)
7809 {
7810   gint x, y;
7811   GtkWindow *window;
7812
7813   window = GTK_WINDOW (data);    
7814   
7815   get_screen_corner (window,
7816                      &x, &y);
7817   
7818   gtk_window_move (window, x, y);
7819 }
7820
7821 static GtkWidget*
7822 make_gravity_window (GtkWidget   *destroy_with,
7823                      GdkGravity   gravity,
7824                      const gchar *title)
7825 {
7826   GtkWidget *window;
7827   GtkWidget *button;
7828   GtkWidget *vbox;
7829   int x, y;
7830   
7831   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7832
7833   gtk_window_set_screen (GTK_WINDOW (window),
7834                          gtk_widget_get_screen (destroy_with));
7835
7836   vbox = gtk_vbox_new (FALSE, 0);
7837   gtk_widget_show (vbox);
7838   
7839   gtk_container_add (GTK_CONTAINER (window), vbox);
7840   gtk_window_set_title (GTK_WINDOW (window), title);
7841   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
7842
7843   g_signal_connect_object (destroy_with,
7844                            "destroy",
7845                            G_CALLBACK (gtk_widget_destroy),
7846                            window,
7847                            G_CONNECT_SWAPPED);
7848
7849   
7850   button = gtk_button_new_with_mnemonic ("_Move to current position");
7851
7852   g_signal_connect (button, "clicked",
7853                     G_CALLBACK (move_gravity_window_to_current_position),
7854                     window);
7855
7856   gtk_container_add (GTK_CONTAINER (vbox), button);
7857   gtk_widget_show (button);
7858
7859   button = gtk_button_new_with_mnemonic ("Move to _starting position");
7860
7861   g_signal_connect (button, "clicked",
7862                     G_CALLBACK (move_gravity_window_to_starting_position),
7863                     window);
7864
7865   gtk_container_add (GTK_CONTAINER (vbox), button);
7866   gtk_widget_show (button);
7867   
7868   /* Pretend this is the result of --geometry.
7869    * DO NOT COPY THIS CODE unless you are setting --geometry results,
7870    * and in that case you probably should just use gtk_window_parse_geometry().
7871    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
7872    * you are parsing --geometry or equivalent.
7873    */
7874   gtk_window_set_geometry_hints (GTK_WINDOW (window),
7875                                  NULL, NULL,
7876                                  GDK_HINT_USER_POS);
7877
7878   gtk_window_set_default_size (GTK_WINDOW (window),
7879                                200, 200);
7880
7881   get_screen_corner (GTK_WINDOW (window), &x, &y);
7882   
7883   gtk_window_move (GTK_WINDOW (window),
7884                    x, y);
7885   
7886   return window;
7887 }
7888
7889 static void
7890 do_gravity_test (GtkWidget *widget,
7891                  gpointer   data)
7892 {
7893   GtkWidget *destroy_with = data;
7894   GtkWidget *window;
7895   
7896   /* We put a window at each gravity point on the screen. */
7897   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
7898                                 "NorthWest");
7899   gtk_widget_show (window);
7900   
7901   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
7902                                 "SouthEast");
7903   gtk_widget_show (window);
7904
7905   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
7906                                 "NorthEast");
7907   gtk_widget_show (window);
7908
7909   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
7910                                 "SouthWest");
7911   gtk_widget_show (window);
7912
7913   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
7914                                 "South");
7915   gtk_widget_show (window);
7916
7917   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
7918                                 "North");
7919   gtk_widget_show (window);
7920
7921   
7922   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
7923                                 "West");
7924   gtk_widget_show (window);
7925
7926     
7927   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
7928                                 "East");
7929   gtk_widget_show (window);
7930
7931   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
7932                                 "Center");
7933   gtk_widget_show (window);
7934
7935   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
7936                                 "Static");
7937   gtk_widget_show (window);
7938 }
7939
7940 static GtkWidget*
7941 window_controls (GtkWidget *window)
7942 {
7943   GtkWidget *control_window;
7944   GtkWidget *label;
7945   GtkWidget *vbox;
7946   GtkWidget *button;
7947   GtkWidget *spin;
7948   GtkAdjustment *adj;
7949   GtkWidget *entry;
7950   GtkWidget *om;
7951   gint i;
7952   
7953   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7954
7955   gtk_window_set_screen (GTK_WINDOW (control_window),
7956                          gtk_widget_get_screen (window));
7957
7958   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
7959   
7960   g_object_set_data (G_OBJECT (control_window),
7961                      "target",
7962                      window);
7963   
7964   g_signal_connect_object (control_window,
7965                            "destroy",
7966                            G_CALLBACK (gtk_widget_destroy),
7967                            window,
7968                            G_CONNECT_SWAPPED);
7969
7970   vbox = gtk_vbox_new (FALSE, 5);
7971   
7972   gtk_container_add (GTK_CONTAINER (control_window), vbox);
7973   
7974   label = gtk_label_new ("<no configure events>");
7975   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7976   
7977   g_signal_connect (window,
7978                     "configure_event",
7979                     G_CALLBACK (configure_event_callback),
7980                     label);
7981
7982   adj = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7983   spin = gtk_spin_button_new (adj, 0, 0);
7984
7985   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7986
7987   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
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), "spin2", spin);
7995
7996   entry = gtk_entry_new ();
7997   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
7998
7999   g_signal_connect (entry, "changed",
8000                     G_CALLBACK (set_geometry_callback),
8001                     control_window);
8002
8003   button = gtk_button_new_with_label ("Show gravity test windows");
8004   g_signal_connect_swapped (button,
8005                             "clicked",
8006                             G_CALLBACK (do_gravity_test),
8007                             control_window);
8008   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8009
8010   button = gtk_button_new_with_label ("Reshow with initial size");
8011   g_signal_connect_object (button,
8012                            "clicked",
8013                            G_CALLBACK (gtk_window_reshow_with_initial_size),
8014                            window,
8015                            G_CONNECT_SWAPPED);
8016   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8017   
8018   button = gtk_button_new_with_label ("Queue resize");
8019   g_signal_connect_object (button,
8020                            "clicked",
8021                            G_CALLBACK (gtk_widget_queue_resize),
8022                            window,
8023                            G_CONNECT_SWAPPED);
8024   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8025   
8026   button = gtk_button_new_with_label ("Resize");
8027   g_signal_connect (button,
8028                     "clicked",
8029                     G_CALLBACK (set_size_callback),
8030                     control_window);
8031   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8032
8033   button = gtk_button_new_with_label ("Set default size");
8034   g_signal_connect (button,
8035                     "clicked",
8036                     G_CALLBACK (set_default_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 ("Unset default size");
8041   g_signal_connect (button,
8042                     "clicked",
8043                     G_CALLBACK (unset_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 ("Set size request");
8048   g_signal_connect (button,
8049                     "clicked",
8050                     G_CALLBACK (set_size_request_callback),
8051                     control_window);
8052   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8053
8054   button = gtk_button_new_with_label ("Unset size request");
8055   g_signal_connect (button,
8056                     "clicked",
8057                     G_CALLBACK (unset_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 ("Move");
8062   g_signal_connect (button,
8063                     "clicked",
8064                     G_CALLBACK (set_location_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 to current position");
8069   g_signal_connect (button,
8070                     "clicked",
8071                     G_CALLBACK (move_to_position_callback),
8072                     control_window);
8073   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8074
8075   button = gtk_check_button_new_with_label ("Allow resize");
8076   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8077   g_signal_connect (button,
8078                     "toggled",
8079                     G_CALLBACK (resizable_callback),
8080                     control_window);
8081   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8082   
8083   button = gtk_button_new_with_mnemonic ("_Show");
8084   g_signal_connect_object (button,
8085                            "clicked",
8086                            G_CALLBACK (gtk_widget_show),
8087                            window,
8088                            G_CONNECT_SWAPPED);
8089   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8090
8091   button = gtk_button_new_with_mnemonic ("_Hide");
8092   g_signal_connect_object (button,
8093                            "clicked",
8094                            G_CALLBACK (gtk_widget_hide),
8095                            window,
8096                            G_CONNECT_SWAPPED);
8097   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8098
8099   om = gtk_combo_box_text_new ();
8100   i = 0;
8101   while (i < 10)
8102     {
8103       static gchar *names[] = {
8104         "GDK_GRAVITY_NORTH_WEST",
8105         "GDK_GRAVITY_NORTH",
8106         "GDK_GRAVITY_NORTH_EAST",
8107         "GDK_GRAVITY_WEST",
8108         "GDK_GRAVITY_CENTER",
8109         "GDK_GRAVITY_EAST",
8110         "GDK_GRAVITY_SOUTH_WEST",
8111         "GDK_GRAVITY_SOUTH",
8112         "GDK_GRAVITY_SOUTH_EAST",
8113         "GDK_GRAVITY_STATIC",
8114         NULL
8115       };
8116
8117       g_assert (names[i]);
8118       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8119
8120       ++i;
8121     }
8122   
8123   g_signal_connect (om,
8124                     "changed",
8125                     G_CALLBACK (gravity_selected),
8126                     control_window);
8127
8128   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8129
8130
8131   om = gtk_combo_box_text_new ();
8132   i = 0;
8133   while (i < 5)
8134     {
8135       static gchar *names[] = {
8136         "GTK_WIN_POS_NONE",
8137         "GTK_WIN_POS_CENTER",
8138         "GTK_WIN_POS_MOUSE",
8139         "GTK_WIN_POS_CENTER_ALWAYS",
8140         "GTK_WIN_POS_CENTER_ON_PARENT",
8141         NULL
8142       };
8143
8144       g_assert (names[i]);
8145       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8146
8147       ++i;
8148     }
8149
8150   g_signal_connect (om,
8151                     "changed",
8152                     G_CALLBACK (pos_selected),
8153                     control_window);
8154
8155   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8156   
8157   gtk_widget_show_all (vbox);
8158   
8159   return control_window;
8160 }
8161
8162 void
8163 create_window_sizing (GtkWidget *widget)
8164 {
8165   static GtkWidget *window = NULL;
8166   static GtkWidget *target_window = NULL;
8167
8168   if (!target_window)
8169     {
8170       GtkWidget *label;
8171       
8172       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8173       gtk_window_set_screen (GTK_WINDOW (target_window),
8174                              gtk_widget_get_screen (widget));
8175       label = gtk_label_new (NULL);
8176       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");
8177       gtk_container_add (GTK_CONTAINER (target_window), label);
8178       gtk_widget_show (label);
8179       
8180       g_signal_connect (target_window, "destroy",
8181                         G_CALLBACK (gtk_widget_destroyed),
8182                         &target_window);
8183
8184       window = window_controls (target_window);
8185       
8186       g_signal_connect (window, "destroy",
8187                         G_CALLBACK (gtk_widget_destroyed),
8188                         &window);
8189       
8190       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
8191     }
8192
8193   /* don't show target window by default, we want to allow testing
8194    * of behavior on first show.
8195    */
8196   
8197   if (!gtk_widget_get_visible (window))
8198     gtk_widget_show (window);
8199   else
8200     gtk_widget_destroy (window);
8201 }
8202
8203 /*
8204  * GtkProgressBar
8205  */
8206
8207 typedef struct _ProgressData {
8208   GtkWidget *window;
8209   GtkWidget *pbar;
8210   GtkWidget *block_spin;
8211   GtkWidget *x_align_spin;
8212   GtkWidget *y_align_spin;
8213   GtkWidget *step_spin;
8214   GtkWidget *act_blocks_spin;
8215   GtkWidget *label;
8216   GtkWidget *omenu1;
8217   GtkWidget *elmenu;
8218   GtkWidget *omenu2;
8219   GtkWidget *entry;
8220   int timer;
8221   gboolean activity;
8222 } ProgressData;
8223
8224 gboolean
8225 progress_timeout (gpointer data)
8226 {
8227   ProgressData *pdata = data;
8228   gdouble new_val;
8229   gchar *text;
8230
8231   if (pdata->activity)
8232     {
8233       gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
8234
8235       text = g_strdup_printf ("%s", "???");
8236     }
8237   else
8238     {
8239       new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
8240       if (new_val > 1.00)
8241         new_val = 0.00;
8242       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
8243
8244       text = g_strdup_printf ("%.0f%%", 100 * new_val);
8245     }
8246
8247   gtk_label_set_text (GTK_LABEL (pdata->label), text);
8248   g_free (text);
8249
8250   return TRUE;
8251 }
8252
8253 static void
8254 destroy_progress (GtkWidget     *widget,
8255                   ProgressData **pdata)
8256 {
8257   g_source_remove ((*pdata)->timer);
8258   (*pdata)->timer = 0;
8259   (*pdata)->window = NULL;
8260   g_free (*pdata);
8261   *pdata = NULL;
8262 }
8263
8264 static void
8265 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
8266 {
8267   ProgressData *pdata;
8268   gint i;
8269
8270   pdata = (ProgressData *) data;
8271
8272   if (!gtk_widget_get_mapped (widget))
8273     return;
8274
8275   i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8276
8277   if (i == 0 || i == 1)
8278     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_HORIZONTAL);
8279   else
8280     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_VERTICAL);
8281  
8282   if (i == 1 || i == 2)
8283     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
8284   else
8285     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
8286 }
8287
8288 static void
8289 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
8290 {
8291   gboolean active;
8292
8293   active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8294   gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), active);
8295 }
8296
8297 static void
8298 progressbar_toggle_ellipsize (GtkWidget *widget,
8299                               gpointer   data)
8300 {
8301   ProgressData *pdata = data;
8302   if (gtk_widget_is_drawable (widget))
8303     {
8304       gint i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8305       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
8306     }
8307 }
8308
8309 static void
8310 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
8311 {
8312   pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8313 }
8314
8315 static void
8316 entry_changed (GtkWidget *widget, ProgressData *pdata)
8317 {
8318   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
8319                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
8320 }
8321
8322 void
8323 create_progress_bar (GtkWidget *widget)
8324 {
8325   GtkWidget *action_area, *content_area;
8326   GtkWidget *button;
8327   GtkWidget *vbox;
8328   GtkWidget *vbox2;
8329   GtkWidget *hbox;
8330   GtkWidget *check;
8331   GtkWidget *frame;
8332   GtkWidget *tab;
8333   GtkWidget *label;
8334   GtkWidget *align;
8335   static ProgressData *pdata = NULL;
8336
8337   static gchar *items1[] =
8338   {
8339     "Left-Right",
8340     "Right-Left",
8341     "Bottom-Top",
8342     "Top-Bottom"
8343   };
8344
8345     static char *ellipsize_items[] = {
8346     "None",     // PANGO_ELLIPSIZE_NONE,
8347     "Start",    // PANGO_ELLIPSIZE_START,
8348     "Middle",   // PANGO_ELLIPSIZE_MIDDLE,
8349     "End",      // PANGO_ELLIPSIZE_END
8350   };
8351   
8352   if (!pdata)
8353     pdata = g_new0 (ProgressData, 1);
8354
8355   if (!pdata->window)
8356     {
8357       pdata->window = gtk_dialog_new ();
8358
8359       gtk_window_set_screen (GTK_WINDOW (pdata->window),
8360                              gtk_widget_get_screen (widget));
8361
8362       gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
8363
8364       g_signal_connect (pdata->window, "destroy",
8365                         G_CALLBACK (destroy_progress),
8366                         &pdata);
8367       pdata->timer = 0;
8368
8369       content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
8370       action_area = gtk_dialog_get_action_area (GTK_DIALOG (pdata->window));
8371
8372       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
8373       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
8374
8375       vbox = gtk_vbox_new (FALSE, 5);
8376       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8377       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
8378
8379       frame = gtk_frame_new ("Progress");
8380       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8381
8382       vbox2 = gtk_vbox_new (FALSE, 5);
8383       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8384
8385       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8386       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8387
8388       pdata->pbar = gtk_progress_bar_new ();
8389       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
8390                                       PANGO_ELLIPSIZE_MIDDLE);
8391
8392       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
8393       pdata->timer = g_timeout_add (100, (GSourceFunc)progress_timeout, pdata);
8394
8395       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8396       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8397
8398       hbox = gtk_hbox_new (FALSE, 5);
8399       gtk_container_add (GTK_CONTAINER (align), hbox);
8400       label = gtk_label_new ("Label updated by user :"); 
8401       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8402       pdata->label = gtk_label_new ("");
8403       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
8404
8405       frame = gtk_frame_new ("Options");
8406       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8407
8408       vbox2 = gtk_vbox_new (FALSE, 5);
8409       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8410
8411       tab = gtk_table_new (7, 2, FALSE);
8412       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
8413
8414       label = gtk_label_new ("Orientation :");
8415       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
8416                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8417                         5, 5);
8418       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8419
8420       pdata->omenu1 = build_option_menu (items1, 4, 0,
8421                                          progressbar_toggle_orientation,
8422                                          pdata);
8423       hbox = gtk_hbox_new (FALSE, 0);
8424       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
8425                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8426                         5, 5);
8427       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
8428       
8429       check = gtk_check_button_new_with_label ("Show text");
8430       g_signal_connect (check, "clicked",
8431                         G_CALLBACK (toggle_show_text),
8432                         pdata);
8433       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
8434                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8435                         5, 5);
8436
8437       hbox = gtk_hbox_new (FALSE, 0);
8438       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
8439                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8440                         5, 5);
8441
8442       label = gtk_label_new ("Text: ");
8443       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8444
8445       pdata->entry = gtk_entry_new ();
8446       g_signal_connect (pdata->entry, "changed",
8447                         G_CALLBACK (entry_changed),
8448                         pdata);
8449       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
8450       gtk_widget_set_size_request (pdata->entry, 100, -1);
8451
8452       label = gtk_label_new ("Ellipsize text :");
8453       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 10, 11,
8454                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8455                         5, 5);
8456       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8457       pdata->elmenu = build_option_menu (ellipsize_items,
8458                                          sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
8459                                          2, // PANGO_ELLIPSIZE_MIDDLE
8460                                          progressbar_toggle_ellipsize,
8461                                          pdata);
8462       hbox = gtk_hbox_new (FALSE, 0);
8463       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 10, 11,
8464                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8465                         5, 5);
8466       gtk_box_pack_start (GTK_BOX (hbox), pdata->elmenu, TRUE, TRUE, 0);
8467
8468       check = gtk_check_button_new_with_label ("Activity mode");
8469       g_signal_connect (check, "clicked",
8470                         G_CALLBACK (toggle_activity_mode), pdata);
8471       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 15, 16,
8472                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8473                         5, 5);
8474
8475       button = gtk_button_new_with_label ("close");
8476       g_signal_connect_swapped (button, "clicked",
8477                                 G_CALLBACK (gtk_widget_destroy),
8478                                 pdata->window);
8479       gtk_widget_set_can_default (button, TRUE);
8480       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8481       gtk_widget_grab_default (button);
8482     }
8483
8484   if (!gtk_widget_get_visible (pdata->window))
8485     gtk_widget_show_all (pdata->window);
8486   else
8487     gtk_widget_destroy (pdata->window);
8488 }
8489
8490 /*
8491  * Properties
8492  */
8493
8494 typedef struct {
8495   int x;
8496   int y;
8497   gboolean found;
8498   gboolean first;
8499   GtkWidget *res_widget;
8500 } FindWidgetData;
8501
8502 static void
8503 find_widget (GtkWidget *widget, FindWidgetData *data)
8504 {
8505   GtkAllocation new_allocation;
8506   gint x_offset = 0;
8507   gint y_offset = 0;
8508
8509   gtk_widget_get_allocation (widget, &new_allocation);
8510
8511   if (data->found || !gtk_widget_get_mapped (widget))
8512     return;
8513
8514   /* Note that in the following code, we only count the
8515    * position as being inside a WINDOW widget if it is inside
8516    * widget->window; points that are outside of widget->window
8517    * but within the allocation are not counted. This is consistent
8518    * with the way we highlight drag targets.
8519    */
8520   if (gtk_widget_get_has_window (widget))
8521     {
8522       new_allocation.x = 0;
8523       new_allocation.y = 0;
8524     }
8525
8526   if (gtk_widget_get_parent (widget) && !data->first)
8527     {
8528       GdkWindow *window = gtk_widget_get_window (widget);
8529       while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
8530         {
8531           gint tx, ty, twidth, theight;
8532           
8533           twidth = gdk_window_get_width (window);
8534           theight = gdk_window_get_height (window);
8535
8536           if (new_allocation.x < 0)
8537             {
8538               new_allocation.width += new_allocation.x;
8539               new_allocation.x = 0;
8540             }
8541           if (new_allocation.y < 0)
8542             {
8543               new_allocation.height += new_allocation.y;
8544               new_allocation.y = 0;
8545             }
8546           if (new_allocation.x + new_allocation.width > twidth)
8547             new_allocation.width = twidth - new_allocation.x;
8548           if (new_allocation.y + new_allocation.height > theight)
8549             new_allocation.height = theight - new_allocation.y;
8550
8551           gdk_window_get_position (window, &tx, &ty);
8552           new_allocation.x += tx;
8553           x_offset += tx;
8554           new_allocation.y += ty;
8555           y_offset += ty;
8556
8557           window = gdk_window_get_parent (window);
8558         }
8559     }
8560
8561   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
8562       (data->x < new_allocation.x + new_allocation.width) && 
8563       (data->y < new_allocation.y + new_allocation.height))
8564     {
8565       /* First, check if the drag is in a valid drop site in
8566        * one of our children 
8567        */
8568       if (GTK_IS_CONTAINER (widget))
8569         {
8570           FindWidgetData new_data = *data;
8571           
8572           new_data.x -= x_offset;
8573           new_data.y -= y_offset;
8574           new_data.found = FALSE;
8575           new_data.first = FALSE;
8576           
8577           gtk_container_forall (GTK_CONTAINER (widget),
8578                                 (GtkCallback)find_widget,
8579                                 &new_data);
8580           
8581           data->found = new_data.found;
8582           if (data->found)
8583             data->res_widget = new_data.res_widget;
8584         }
8585
8586       /* If not, and this widget is registered as a drop site, check to
8587        * emit "drag_motion" to check if we are actually in
8588        * a drop site.
8589        */
8590       if (!data->found)
8591         {
8592           data->found = TRUE;
8593           data->res_widget = widget;
8594         }
8595     }
8596 }
8597
8598 static GtkWidget *
8599 find_widget_at_pointer (GdkDisplay *display)
8600 {
8601   GtkWidget *widget = NULL;
8602   GdkWindow *pointer_window;
8603   gint x, y;
8604   FindWidgetData data;
8605  
8606  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
8607  
8608  if (pointer_window)
8609    {
8610      gpointer widget_ptr;
8611
8612      gdk_window_get_user_data (pointer_window, &widget_ptr);
8613      widget = widget_ptr;
8614    }
8615
8616  if (widget)
8617    {
8618      gdk_window_get_pointer (gtk_widget_get_window (widget),
8619                              &x, &y, NULL);
8620      
8621      data.x = x;
8622      data.y = y;
8623      data.found = FALSE;
8624      data.first = TRUE;
8625
8626      find_widget (widget, &data);
8627      if (data.found)
8628        return data.res_widget;
8629      return widget;
8630    }
8631  return NULL;
8632 }
8633
8634 struct PropertiesData {
8635   GtkWidget **window;
8636   GdkCursor *cursor;
8637   gboolean in_query;
8638   gint handler;
8639 };
8640
8641 static void
8642 destroy_properties (GtkWidget             *widget,
8643                     struct PropertiesData *data)
8644 {
8645   if (data->window)
8646     {
8647       *data->window = NULL;
8648       data->window = NULL;
8649     }
8650
8651   if (data->cursor)
8652     {
8653       gdk_cursor_unref (data->cursor);
8654       data->cursor = NULL;
8655     }
8656
8657   if (data->handler)
8658     {
8659       g_signal_handler_disconnect (widget, data->handler);
8660       data->handler = 0;
8661     }
8662
8663   g_free (data);
8664 }
8665
8666 static gint
8667 property_query_event (GtkWidget        *widget,
8668                       GdkEvent         *event,
8669                       struct PropertiesData *data)
8670 {
8671   GtkWidget *res_widget = NULL;
8672
8673   if (!data->in_query)
8674     return FALSE;
8675   
8676   if (event->type == GDK_BUTTON_RELEASE)
8677     {
8678       gtk_grab_remove (widget);
8679       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
8680                                   GDK_CURRENT_TIME);
8681       
8682       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
8683       if (res_widget)
8684         {
8685           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
8686                              gtk_widget_get_screen (widget));
8687           create_prop_editor (G_OBJECT (res_widget), 0);
8688         }
8689
8690       data->in_query = FALSE;
8691     }
8692   return FALSE;
8693 }
8694
8695
8696 static void
8697 query_properties (GtkButton *button,
8698                   struct PropertiesData *data)
8699 {
8700   GtkWidget *widget = GTK_WIDGET (button);
8701   gint failure;
8702
8703   g_signal_connect (button, "event",
8704                     G_CALLBACK (property_query_event), data);
8705
8706
8707   if (!data->cursor)
8708     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8709                                                GDK_TARGET);
8710
8711   failure = gdk_pointer_grab (gtk_widget_get_window (widget),
8712                               TRUE,
8713                               GDK_BUTTON_RELEASE_MASK,
8714                               NULL,
8715                               data->cursor,
8716                               GDK_CURRENT_TIME);
8717
8718   gtk_grab_add (widget);
8719
8720   data->in_query = TRUE;
8721 }
8722
8723 static void
8724 create_properties (GtkWidget *widget)
8725 {
8726   static GtkWidget *window = NULL;
8727   GtkWidget *button;
8728   GtkWidget *vbox;
8729   GtkWidget *label;
8730   struct PropertiesData *data;
8731
8732   data = g_new (struct PropertiesData, 1);
8733   data->window = &window;
8734   data->in_query = FALSE;
8735   data->cursor = NULL;
8736   data->handler = 0;
8737
8738   if (!window)
8739     {
8740       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8741
8742       gtk_window_set_screen (GTK_WINDOW (window),
8743                              gtk_widget_get_screen (widget));      
8744
8745       data->handler = g_signal_connect (window, "destroy",
8746                                         G_CALLBACK (destroy_properties),
8747                                         data);
8748
8749       gtk_window_set_title (GTK_WINDOW (window), "test properties");
8750       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8751
8752       vbox = gtk_vbox_new (FALSE, 1);
8753       gtk_container_add (GTK_CONTAINER (window), vbox);
8754             
8755       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
8756       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
8757       
8758       button = gtk_button_new_with_label ("Query properties");
8759       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8760       g_signal_connect (button, "clicked",
8761                         G_CALLBACK (query_properties),
8762                         data);
8763     }
8764
8765   if (!gtk_widget_get_visible (window))
8766     gtk_widget_show_all (window);
8767   else
8768     gtk_widget_destroy (window);
8769   
8770 }
8771
8772 struct SnapshotData {
8773   GtkWidget *toplevel_button;
8774   GtkWidget **window;
8775   GdkCursor *cursor;
8776   gboolean in_query;
8777   gboolean is_toplevel;
8778   gint handler;
8779 };
8780
8781 static void
8782 destroy_snapshot_data (GtkWidget             *widget,
8783                        struct SnapshotData *data)
8784 {
8785   if (*data->window)
8786     *data->window = NULL;
8787   
8788   if (data->cursor)
8789     {
8790       gdk_cursor_unref (data->cursor);
8791       data->cursor = NULL;
8792     }
8793
8794   if (data->handler)
8795     {
8796       g_signal_handler_disconnect (widget, data->handler);
8797       data->handler = 0;
8798     }
8799
8800   g_free (data);
8801 }
8802
8803 static gint
8804 snapshot_widget_event (GtkWidget               *widget,
8805                        GdkEvent        *event,
8806                        struct SnapshotData *data)
8807 {
8808   GtkWidget *res_widget = NULL;
8809
8810   if (!data->in_query)
8811     return FALSE;
8812   
8813   if (event->type == GDK_BUTTON_RELEASE)
8814     {
8815       gtk_grab_remove (widget);
8816       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
8817                                   GDK_CURRENT_TIME);
8818       
8819       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
8820       if (data->is_toplevel && res_widget)
8821         res_widget = gtk_widget_get_toplevel (res_widget);
8822       if (res_widget)
8823         {
8824           cairo_surface_t *surface;
8825           GtkWidget *window, *image;
8826           GdkPixbuf *pixbuf;
8827           int width, height;
8828           cairo_t *cr;
8829
8830           width = gtk_widget_get_allocated_width (res_widget);
8831           height = gtk_widget_get_allocated_height (res_widget);
8832
8833           surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
8834
8835           cr = cairo_create (surface);
8836           gtk_widget_draw (res_widget, cr);
8837           cairo_destroy (cr);
8838
8839           pixbuf = gdk_pixbuf_get_from_surface (surface,
8840                                                 0, 0,
8841                                                 width, height);
8842           cairo_surface_destroy (surface);
8843
8844           window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8845           image = gtk_image_new_from_pixbuf (pixbuf);
8846           g_object_unref (pixbuf);
8847
8848           gtk_container_add (GTK_CONTAINER (window), image);
8849           gtk_widget_show_all (window);
8850         }
8851
8852       data->in_query = FALSE;
8853     }
8854   return FALSE;
8855 }
8856
8857
8858 static void
8859 snapshot_widget (GtkButton *button,
8860                  struct SnapshotData *data)
8861 {
8862   GtkWidget *widget = GTK_WIDGET (button);
8863   gint failure;
8864
8865   g_signal_connect (button, "event",
8866                     G_CALLBACK (snapshot_widget_event), data);
8867
8868   data->is_toplevel = widget == data->toplevel_button;
8869
8870   if (!data->cursor)
8871     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8872                                                GDK_TARGET);
8873
8874   failure = gdk_pointer_grab (gtk_widget_get_window (widget),
8875                               TRUE,
8876                               GDK_BUTTON_RELEASE_MASK,
8877                               NULL,
8878                               data->cursor,
8879                               GDK_CURRENT_TIME);
8880
8881   gtk_grab_add (widget);
8882
8883   data->in_query = TRUE;
8884 }
8885
8886 static void
8887 create_snapshot (GtkWidget *widget)
8888 {
8889   static GtkWidget *window = NULL;
8890   GtkWidget *button;
8891   GtkWidget *vbox;
8892   struct SnapshotData *data;
8893
8894   data = g_new (struct SnapshotData, 1);
8895   data->window = &window;
8896   data->in_query = FALSE;
8897   data->cursor = NULL;
8898   data->handler = 0;
8899
8900   if (!window)
8901     {
8902       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8903
8904       gtk_window_set_screen (GTK_WINDOW (window),
8905                              gtk_widget_get_screen (widget));      
8906
8907       data->handler = g_signal_connect (window, "destroy",
8908                                         G_CALLBACK (destroy_snapshot_data),
8909                                         data);
8910
8911       gtk_window_set_title (GTK_WINDOW (window), "test snapshot");
8912       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8913
8914       vbox = gtk_vbox_new (FALSE, 1);
8915       gtk_container_add (GTK_CONTAINER (window), vbox);
8916             
8917       button = gtk_button_new_with_label ("Snapshot widget");
8918       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8919       g_signal_connect (button, "clicked",
8920                         G_CALLBACK (snapshot_widget),
8921                         data);
8922       
8923       button = gtk_button_new_with_label ("Snapshot toplevel");
8924       data->toplevel_button = button;
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
8931   if (!gtk_widget_get_visible (window))
8932     gtk_widget_show_all (window);
8933   else
8934     gtk_widget_destroy (window);
8935   
8936 }
8937
8938 /*
8939  * Selection Test
8940  */
8941
8942 void
8943 selection_test_received (GtkWidget        *tree_view,
8944                          GtkSelectionData *data)
8945 {
8946   GtkTreeModel *model;
8947   GtkListStore *store;
8948   GdkAtom *atoms;
8949   int i, l;
8950
8951   if (data->length < 0)
8952     {
8953       g_print ("Selection retrieval failed\n");
8954       return;
8955     }
8956   if (data->type != GDK_SELECTION_TYPE_ATOM)
8957     {
8958       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
8959       return;
8960     }
8961
8962   /* Clear out any current list items */
8963
8964   model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
8965   store = GTK_LIST_STORE (model);
8966   gtk_list_store_clear (store);
8967
8968   /* Add new items to list */
8969
8970   atoms = (GdkAtom *)data->data;
8971
8972   l = data->length / sizeof (GdkAtom);
8973   for (i = 0; i < l; i++)
8974     {
8975       char *name;
8976       GtkTreeIter iter;
8977
8978       name = gdk_atom_name (atoms[i]);
8979       if (name != NULL)
8980         {
8981           gtk_list_store_insert_with_values (store, &iter, i, 0, name, -1);
8982           g_free (name);
8983         }
8984       else
8985        gtk_list_store_insert_with_values (store, &iter, i, 0,  "(bad atom)", -1);
8986     }
8987
8988   return;
8989 }
8990
8991 void
8992 selection_test_get_targets (GtkWidget *widget, GtkWidget *tree_view)
8993 {
8994   static GdkAtom targets_atom = GDK_NONE;
8995
8996   if (targets_atom == GDK_NONE)
8997     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
8998
8999   gtk_selection_convert (tree_view, GDK_SELECTION_PRIMARY, targets_atom,
9000                          GDK_CURRENT_TIME);
9001 }
9002
9003 void
9004 create_selection_test (GtkWidget *widget)
9005 {
9006   static GtkWidget *window = NULL;
9007   GtkWidget *action_area, *content_area;
9008   GtkWidget *button;
9009   GtkWidget *vbox;
9010   GtkWidget *scrolled_win;
9011   GtkListStore* store;
9012   GtkWidget *tree_view;
9013   GtkTreeViewColumn *column;
9014   GtkCellRenderer *renderer;
9015   GtkWidget *label;
9016
9017   if (!window)
9018     {
9019       window = gtk_dialog_new ();
9020       
9021       gtk_window_set_screen (GTK_WINDOW (window),
9022                              gtk_widget_get_screen (widget));
9023
9024       g_signal_connect (window, "destroy",
9025                         G_CALLBACK (gtk_widget_destroyed),
9026                         &window);
9027
9028       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9029       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9030
9031       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
9032       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9033
9034       /* Create the list */
9035
9036       vbox = gtk_vbox_new (FALSE, 5);
9037       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9038       gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
9039
9040       label = gtk_label_new ("Gets available targets for current selection");
9041       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9042
9043       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
9044       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
9045                                       GTK_POLICY_AUTOMATIC, 
9046                                       GTK_POLICY_AUTOMATIC);
9047       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
9048       gtk_widget_set_size_request (scrolled_win, 100, 200);
9049
9050       store = gtk_list_store_new (1, G_TYPE_STRING);
9051       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
9052       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), tree_view);
9053
9054       renderer = gtk_cell_renderer_text_new ();
9055       column = gtk_tree_view_column_new_with_attributes ("Target", renderer,
9056                                                          "text", 0, NULL);
9057       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
9058
9059       g_signal_connect (tree_view, "selection_received",
9060                         G_CALLBACK (selection_test_received), NULL);
9061
9062       /* .. And create some buttons */
9063       button = gtk_button_new_with_label ("Get Targets");
9064       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9065
9066       g_signal_connect (button, "clicked",
9067                         G_CALLBACK (selection_test_get_targets), tree_view);
9068
9069       button = gtk_button_new_with_label ("Quit");
9070       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9071
9072       g_signal_connect_swapped (button, "clicked",
9073                                 G_CALLBACK (gtk_widget_destroy),
9074                                 window);
9075     }
9076
9077   if (!gtk_widget_get_visible (window))
9078     gtk_widget_show_all (window);
9079   else
9080     gtk_widget_destroy (window);
9081 }
9082
9083 /*
9084  * Test scrolling
9085  */
9086
9087 static int scroll_test_pos = 0.0;
9088
9089 static gint
9090 scroll_test_draw (GtkWidget     *widget,
9091                   cairo_t       *cr,
9092                   GtkAdjustment *adj)
9093 {
9094   gint i,j;
9095   gint imin, imax, jmin, jmax;
9096   GdkRectangle clip;
9097   
9098   gdk_cairo_get_clip_rectangle (cr, &clip);
9099
9100   imin = (clip.x) / 10;
9101   imax = (clip.x + clip.width + 9) / 10;
9102
9103   jmin = ((int)adj->value + clip.y) / 10;
9104   jmax = ((int)adj->value + clip.y + clip.height + 9) / 10;
9105
9106   for (i=imin; i<imax; i++)
9107     for (j=jmin; j<jmax; j++)
9108       if ((i+j) % 2)
9109         cairo_rectangle (cr, 10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
9110
9111   cairo_fill (cr);
9112
9113   return TRUE;
9114 }
9115
9116 static gint
9117 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
9118                     GtkAdjustment *adj)
9119 {
9120   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
9121                                     -adj->page_increment / 2:
9122                                     adj->page_increment / 2);
9123   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
9124   gtk_adjustment_set_value (adj, new_value);  
9125   
9126   return TRUE;
9127 }
9128
9129 static void
9130 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
9131                        GtkAdjustment *adj)
9132 {
9133   GtkAllocation allocation;
9134
9135   gtk_widget_get_allocation (widget, &allocation);
9136   adj->page_increment = 0.9 * allocation.height;
9137   adj->page_size = allocation.height;
9138
9139   g_signal_emit_by_name (adj, "changed");
9140 }
9141
9142 static void
9143 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
9144 {
9145   GdkWindow *window;
9146   gint dy;
9147
9148   dy = scroll_test_pos - (int)adj->value;
9149   scroll_test_pos = adj->value;
9150
9151   if (!gtk_widget_is_drawable (widget))
9152     return;
9153
9154   window = gtk_widget_get_window (widget);
9155   gdk_window_scroll (window, 0, dy);
9156   gdk_window_process_updates (window, FALSE);
9157 }
9158
9159
9160 void
9161 create_scroll_test (GtkWidget *widget)
9162 {
9163   static GtkWidget *window = NULL;
9164   GtkWidget *action_area, *content_area;
9165   GtkWidget *hbox;
9166   GtkWidget *drawing_area;
9167   GtkWidget *scrollbar;
9168   GtkWidget *button;
9169   GtkAdjustment *adj;
9170   GdkGeometry geometry;
9171   GdkWindowHints geometry_mask;
9172
9173   if (!window)
9174     {
9175       window = gtk_dialog_new ();
9176
9177       gtk_window_set_screen (GTK_WINDOW (window),
9178                              gtk_widget_get_screen (widget));
9179
9180       g_signal_connect (window, "destroy",
9181                         G_CALLBACK (gtk_widget_destroyed),
9182                         &window);
9183
9184       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9185       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9186
9187       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
9188       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9189
9190       hbox = gtk_hbox_new (FALSE, 0);
9191       gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
9192       gtk_widget_show (hbox);
9193
9194       drawing_area = gtk_drawing_area_new ();
9195       gtk_widget_set_size_request (drawing_area, 200, 200);
9196       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
9197       gtk_widget_show (drawing_area);
9198
9199       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
9200
9201       adj = gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0);
9202       scroll_test_pos = 0.0;
9203
9204       scrollbar = gtk_vscrollbar_new (adj);
9205       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
9206       gtk_widget_show (scrollbar);
9207
9208       g_signal_connect (drawing_area, "draw",
9209                         G_CALLBACK (scroll_test_draw), adj);
9210       g_signal_connect (drawing_area, "configure_event",
9211                         G_CALLBACK (scroll_test_configure), adj);
9212       g_signal_connect (drawing_area, "scroll_event",
9213                         G_CALLBACK (scroll_test_scroll), adj);
9214       
9215       g_signal_connect (adj, "value_changed",
9216                         G_CALLBACK (scroll_test_adjustment_changed),
9217                         drawing_area);
9218       
9219       /* .. And create some buttons */
9220
9221       button = gtk_button_new_with_label ("Quit");
9222       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9223
9224       g_signal_connect_swapped (button, "clicked",
9225                                 G_CALLBACK (gtk_widget_destroy),
9226                                 window);
9227       gtk_widget_show (button);
9228
9229       /* Set up gridded geometry */
9230
9231       geometry_mask = GDK_HINT_MIN_SIZE | 
9232                        GDK_HINT_BASE_SIZE | 
9233                        GDK_HINT_RESIZE_INC;
9234
9235       geometry.min_width = 20;
9236       geometry.min_height = 20;
9237       geometry.base_width = 0;
9238       geometry.base_height = 0;
9239       geometry.width_inc = 10;
9240       geometry.height_inc = 10;
9241       
9242       gtk_window_set_geometry_hints (GTK_WINDOW (window),
9243                                drawing_area, &geometry, geometry_mask);
9244     }
9245
9246   if (!gtk_widget_get_visible (window))
9247     gtk_widget_show (window);
9248   else
9249     gtk_widget_destroy (window);
9250 }
9251
9252 /*
9253  * Timeout Test
9254  */
9255
9256 static int timer = 0;
9257
9258 gint
9259 timeout_test (GtkWidget *label)
9260 {
9261   static int count = 0;
9262   static char buffer[32];
9263
9264   sprintf (buffer, "count: %d", ++count);
9265   gtk_label_set_text (GTK_LABEL (label), buffer);
9266
9267   return TRUE;
9268 }
9269
9270 void
9271 start_timeout_test (GtkWidget *widget,
9272                     GtkWidget *label)
9273 {
9274   if (!timer)
9275     {
9276       timer = g_timeout_add (100, (GSourceFunc)timeout_test, label);
9277     }
9278 }
9279
9280 void
9281 stop_timeout_test (GtkWidget *widget,
9282                    gpointer   data)
9283 {
9284   if (timer)
9285     {
9286       g_source_remove (timer);
9287       timer = 0;
9288     }
9289 }
9290
9291 void
9292 destroy_timeout_test (GtkWidget  *widget,
9293                       GtkWidget **window)
9294 {
9295   stop_timeout_test (NULL, NULL);
9296
9297   *window = NULL;
9298 }
9299
9300 void
9301 create_timeout_test (GtkWidget *widget)
9302 {
9303   static GtkWidget *window = NULL;
9304   GtkWidget *action_area, *content_area;
9305   GtkWidget *button;
9306   GtkWidget *label;
9307
9308   if (!window)
9309     {
9310       window = gtk_dialog_new ();
9311
9312       gtk_window_set_screen (GTK_WINDOW (window),
9313                              gtk_widget_get_screen (widget));
9314
9315       g_signal_connect (window, "destroy",
9316                         G_CALLBACK (destroy_timeout_test),
9317                         &window);
9318
9319       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9320       action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9321
9322       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
9323       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9324
9325       label = gtk_label_new ("count: 0");
9326       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
9327       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9328       gtk_widget_show (label);
9329
9330       button = gtk_button_new_with_label ("close");
9331       g_signal_connect_swapped (button, "clicked",
9332                                 G_CALLBACK (gtk_widget_destroy),
9333                                 window);
9334       gtk_widget_set_can_default (button, TRUE);
9335       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9336       gtk_widget_grab_default (button);
9337       gtk_widget_show (button);
9338
9339       button = gtk_button_new_with_label ("start");
9340       g_signal_connect (button, "clicked",
9341                         G_CALLBACK(start_timeout_test),
9342                         label);
9343       gtk_widget_set_can_default (button, TRUE);
9344       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9345       gtk_widget_show (button);
9346
9347       button = gtk_button_new_with_label ("stop");
9348       g_signal_connect (button, "clicked",
9349                         G_CALLBACK (stop_timeout_test),
9350                         NULL);
9351       gtk_widget_set_can_default (button, TRUE);
9352       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9353       gtk_widget_show (button);
9354     }
9355
9356   if (!gtk_widget_get_visible (window))
9357     gtk_widget_show (window);
9358   else
9359     gtk_widget_destroy (window);
9360 }
9361
9362 /*
9363  * Idle Test
9364  */
9365
9366 static int idle_id = 0;
9367
9368 static gint
9369 idle_test (GtkWidget *label)
9370 {
9371   static int count = 0;
9372   static char buffer[32];
9373
9374   sprintf (buffer, "count: %d", ++count);
9375   gtk_label_set_text (GTK_LABEL (label), buffer);
9376
9377   return TRUE;
9378 }
9379
9380 static void
9381 start_idle_test (GtkWidget *widget,
9382                  GtkWidget *label)
9383 {
9384   if (!idle_id)
9385     {
9386       idle_id = g_idle_add ((GSourceFunc) idle_test, label);
9387     }
9388 }
9389
9390 static void
9391 stop_idle_test (GtkWidget *widget,
9392                 gpointer   data)
9393 {
9394   if (idle_id)
9395     {
9396       g_source_remove (idle_id);
9397       idle_id = 0;
9398     }
9399 }
9400
9401 static void
9402 destroy_idle_test (GtkWidget  *widget,
9403                    GtkWidget **window)
9404 {
9405   stop_idle_test (NULL, NULL);
9406
9407   *window = NULL;
9408 }
9409
9410 static void
9411 toggle_idle_container (GObject *button,
9412                        GtkContainer *container)
9413 {
9414   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
9415 }
9416
9417 static void
9418 create_idle_test (GtkWidget *widget)
9419 {
9420   static GtkWidget *window = NULL;
9421   GtkWidget *button;
9422   GtkWidget *label;
9423   GtkWidget *container;
9424
9425   if (!window)
9426     {
9427       GtkWidget *action_area, *content_area;
9428       GtkWidget *button2;
9429       GtkWidget *frame;
9430       GtkWidget *box;
9431
9432       window = gtk_dialog_new ();
9433
9434       gtk_window_set_screen (GTK_WINDOW (window),
9435                              gtk_widget_get_screen (widget));
9436
9437       g_signal_connect (window, "destroy",
9438                         G_CALLBACK (destroy_idle_test),
9439                         &window);
9440
9441       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9442       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9443
9444       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
9445       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9446
9447       label = gtk_label_new ("count: 0");
9448       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
9449       gtk_widget_show (label);
9450       
9451       container =
9452         g_object_new (GTK_TYPE_HBOX,
9453                         "visible", TRUE,
9454                         /* "GtkContainer::child", g_object_new (GTK_TYPE_HBOX,
9455                          * "GtkWidget::visible", TRUE,
9456                          */
9457                          "child", label,
9458                         /* NULL), */
9459                         NULL);
9460       gtk_box_pack_start (GTK_BOX (content_area), container, TRUE, TRUE, 0);
9461
9462       frame =
9463         g_object_new (GTK_TYPE_FRAME,
9464                         "border_width", 5,
9465                         "label", "Label Container",
9466                         "visible", TRUE,
9467                         "parent", content_area,
9468                         NULL);
9469       box =
9470         g_object_new (GTK_TYPE_VBOX,
9471                         "visible", TRUE,
9472                         "parent", frame,
9473                         NULL);
9474       button =
9475         g_object_connect (g_object_new (GTK_TYPE_RADIO_BUTTON,
9476                                           "label", "Resize-Parent",
9477                                           "user_data", (void*)GTK_RESIZE_PARENT,
9478                                           "visible", TRUE,
9479                                           "parent", box,
9480                                           NULL),
9481                           "signal::clicked", toggle_idle_container, container,
9482                           NULL);
9483       button = g_object_new (GTK_TYPE_RADIO_BUTTON,
9484                                "label", "Resize-Queue",
9485                                "user_data", (void*)GTK_RESIZE_QUEUE,
9486                                "group", button,
9487                                "visible", TRUE,
9488                                "parent", box,
9489                                NULL);
9490       g_object_connect (button,
9491                         "signal::clicked", toggle_idle_container, container,
9492                         NULL);
9493       button2 = g_object_new (GTK_TYPE_RADIO_BUTTON,
9494                                 "label", "Resize-Immediate",
9495                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
9496                                 NULL);
9497       g_object_connect (button2,
9498                         "signal::clicked", toggle_idle_container, container,
9499                         NULL);
9500       g_object_set (button2,
9501                     "group", button,
9502                     "visible", TRUE,
9503                     "parent", box,
9504                     NULL);
9505
9506       button = gtk_button_new_with_label ("close");
9507       g_signal_connect_swapped (button, "clicked",
9508                                 G_CALLBACK (gtk_widget_destroy),
9509                                 window);
9510       gtk_widget_set_can_default (button, TRUE);
9511       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9512       gtk_widget_grab_default (button);
9513       gtk_widget_show (button);
9514
9515       button = gtk_button_new_with_label ("start");
9516       g_signal_connect (button, "clicked",
9517                         G_CALLBACK (start_idle_test),
9518                         label);
9519       gtk_widget_set_can_default (button, TRUE);
9520       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9521       gtk_widget_show (button);
9522
9523       button = gtk_button_new_with_label ("stop");
9524       g_signal_connect (button, "clicked",
9525                         G_CALLBACK (stop_idle_test),
9526                         NULL);
9527       gtk_widget_set_can_default (button, TRUE);
9528       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9529       gtk_widget_show (button);
9530     }
9531
9532   if (!gtk_widget_get_visible (window))
9533     gtk_widget_show (window);
9534   else
9535     gtk_widget_destroy (window);
9536 }
9537
9538 /*
9539  * rc file test
9540  */
9541
9542 void
9543 reload_all_rc_files (void)
9544 {
9545   static GdkAtom atom_rcfiles = GDK_NONE;
9546
9547   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
9548   int i;
9549   
9550   if (!atom_rcfiles)
9551     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
9552
9553   for(i = 0; i < 5; i++)
9554     send_event->client.data.l[i] = 0;
9555   send_event->client.data_format = 32;
9556   send_event->client.message_type = atom_rcfiles;
9557   gdk_event_send_clientmessage_toall (send_event);
9558
9559   gdk_event_free (send_event);
9560 }
9561
9562 void
9563 create_rc_file (GtkWidget *widget)
9564 {
9565   static GtkWidget *window = NULL;
9566   GtkWidget *action_area, *content_area;
9567   GtkWidget *button;
9568   GtkWidget *frame;
9569   GtkWidget *vbox;
9570   GtkWidget *label;
9571
9572   if (!window)
9573     {
9574       window = gtk_dialog_new ();
9575
9576       gtk_window_set_screen (GTK_WINDOW (window),
9577                              gtk_widget_get_screen (widget));
9578
9579       g_signal_connect (window, "destroy",
9580                         G_CALLBACK (gtk_widget_destroyed),
9581                         &window);
9582
9583       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9584       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9585
9586       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
9587       gtk_box_pack_start (GTK_BOX (content_area), frame, FALSE, FALSE, 0);
9588
9589       vbox = gtk_vbox_new (FALSE, 0);
9590       gtk_container_add (GTK_CONTAINER (frame), vbox);
9591       
9592       label = gtk_label_new ("This label should be red");
9593       gtk_widget_set_name (label, "testgtk-red-label");
9594       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9595
9596       label = gtk_label_new ("This label should be green");
9597       gtk_widget_set_name (label, "testgtk-green-label");
9598       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9599
9600       label = gtk_label_new ("This label should be blue");
9601       gtk_widget_set_name (label, "testgtk-blue-label");
9602       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9603
9604       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
9605       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9606
9607       button = gtk_button_new_with_label ("Reload");
9608       g_signal_connect (button, "clicked",
9609                         G_CALLBACK (gtk_rc_reparse_all), NULL);
9610       gtk_widget_set_can_default (button, TRUE);
9611       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9612       gtk_widget_grab_default (button);
9613
9614       button = gtk_button_new_with_label ("Reload All");
9615       g_signal_connect (button, "clicked",
9616                         G_CALLBACK (reload_all_rc_files), NULL);
9617       gtk_widget_set_can_default (button, TRUE);
9618       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9619
9620       button = gtk_button_new_with_label ("Close");
9621       g_signal_connect_swapped (button, "clicked",
9622                                 G_CALLBACK (gtk_widget_destroy),
9623                                 window);
9624       gtk_widget_set_can_default (button, TRUE);
9625       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9626     }
9627
9628   if (!gtk_widget_get_visible (window))
9629     gtk_widget_show_all (window);
9630   else
9631     gtk_widget_destroy (window);
9632 }
9633
9634 /*
9635  * Test of recursive mainloop
9636  */
9637
9638 void
9639 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
9640 {
9641   *window = NULL;
9642   gtk_main_quit ();
9643 }
9644
9645 void
9646 create_mainloop (GtkWidget *widget)
9647 {
9648   static GtkWidget *window = NULL;
9649   GtkWidget *action_area, *content_area;
9650   GtkWidget *label;
9651   GtkWidget *button;
9652
9653   if (!window)
9654     {
9655       window = gtk_dialog_new ();
9656
9657       gtk_window_set_screen (GTK_WINDOW (window),
9658                              gtk_widget_get_screen (widget));
9659
9660       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
9661
9662       g_signal_connect (window, "destroy",
9663                         G_CALLBACK (mainloop_destroyed),
9664                         &window);
9665
9666       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9667       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9668
9669       label = gtk_label_new ("In recursive main loop...");
9670       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
9671
9672       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9673       gtk_widget_show (label);
9674
9675       button = gtk_button_new_with_label ("Leave");
9676       gtk_box_pack_start (GTK_BOX (action_area), button, FALSE, TRUE, 0);
9677
9678       g_signal_connect_swapped (button, "clicked",
9679                                 G_CALLBACK (gtk_widget_destroy),
9680                                 window);
9681
9682       gtk_widget_set_can_default (button, TRUE);
9683       gtk_widget_grab_default (button);
9684
9685       gtk_widget_show (button);
9686     }
9687
9688   if (!gtk_widget_get_visible (window))
9689     {
9690       gtk_widget_show (window);
9691
9692       g_print ("create_mainloop: start\n");
9693       gtk_main ();
9694       g_print ("create_mainloop: done\n");
9695     }
9696   else
9697     gtk_widget_destroy (window);
9698 }
9699
9700 static gboolean
9701 layout_draw_handler (GtkWidget *widget, cairo_t *cr)
9702 {
9703   GtkLayout *layout;
9704   GdkWindow *bin_window;
9705   GdkRectangle clip;
9706   gint i,j,x,y;
9707   gint imin, imax, jmin, jmax;
9708
9709   layout = GTK_LAYOUT (widget);
9710   bin_window = gtk_layout_get_bin_window (layout);
9711
9712   if (!gtk_cairo_should_draw_window (cr, bin_window))
9713     return FALSE;
9714   
9715   gdk_window_get_position (bin_window, &x, &y);
9716   cairo_translate (cr, x, y);
9717
9718   gdk_cairo_get_clip_rectangle (cr, &clip);
9719
9720   imin = (clip.x) / 10;
9721   imax = (clip.x + clip.width + 9) / 10;
9722
9723   jmin = (clip.y) / 10;
9724   jmax = (clip.y + clip.height + 9) / 10;
9725
9726   for (i=imin; i<imax; i++)
9727     for (j=jmin; j<jmax; j++)
9728       if ((i+j) % 2)
9729         cairo_rectangle (cr,
9730                          10*i, 10*j, 
9731                          1+i%10, 1+j%10);
9732   
9733   cairo_fill (cr);
9734
9735   return FALSE;
9736 }
9737
9738 void create_layout (GtkWidget *widget)
9739 {
9740   GtkAdjustment *hadjustment, *vadjustment;
9741   GtkLayout *layout;
9742   static GtkWidget *window = NULL;
9743   GtkWidget *layout_widget;
9744   GtkWidget *scrolledwindow;
9745   GtkWidget *button;
9746
9747   if (!window)
9748     {
9749       gchar buf[16];
9750
9751       gint i, j;
9752       
9753       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9754       gtk_window_set_screen (GTK_WINDOW (window),
9755                              gtk_widget_get_screen (widget));
9756
9757       g_signal_connect (window, "destroy",
9758                         G_CALLBACK (gtk_widget_destroyed),
9759                         &window);
9760
9761       gtk_window_set_title (GTK_WINDOW (window), "Layout");
9762       gtk_widget_set_size_request (window, 200, 200);
9763
9764       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
9765       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
9766                                            GTK_SHADOW_IN);
9767       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
9768                                          GTK_CORNER_TOP_RIGHT);
9769
9770       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
9771
9772       layout_widget = gtk_layout_new (NULL, NULL);
9773       layout = GTK_LAYOUT (layout_widget);
9774       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);
9775
9776       /* We set step sizes here since GtkLayout does not set
9777        * them itself.
9778        */
9779       hadjustment = gtk_layout_get_hadjustment (layout);
9780       vadjustment = gtk_layout_get_vadjustment (layout);
9781       gtk_adjustment_set_step_increment (hadjustment, 10.0);
9782       gtk_adjustment_set_step_increment (vadjustment, 10.0);
9783       gtk_layout_set_hadjustment (layout, hadjustment);
9784       gtk_layout_set_vadjustment (layout, vadjustment);
9785
9786       gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
9787       g_signal_connect (layout, "draw",
9788                         G_CALLBACK (layout_draw_handler), NULL);
9789
9790       gtk_layout_set_size (layout, 1600, 128000);
9791
9792       for (i=0 ; i < 16 ; i++)
9793         for (j=0 ; j < 16 ; j++)
9794           {
9795             sprintf(buf, "Button %d, %d", i, j);
9796             if ((i + j) % 2)
9797               button = gtk_button_new_with_label (buf);
9798             else
9799               button = gtk_label_new (buf);
9800
9801             gtk_layout_put (layout, button, j*100, i*100);
9802           }
9803
9804       for (i=16; i < 1280; i++)
9805         {
9806           sprintf(buf, "Button %d, %d", i, 0);
9807           if (i % 2)
9808             button = gtk_button_new_with_label (buf);
9809           else
9810             button = gtk_label_new (buf);
9811
9812           gtk_layout_put (layout, button, 0, i*100);
9813         }
9814     }
9815
9816   if (!gtk_widget_get_visible (window))
9817     gtk_widget_show_all (window);
9818   else
9819     gtk_widget_destroy (window);
9820 }
9821
9822 void
9823 create_styles (GtkWidget *widget)
9824 {
9825   static GtkWidget *window = NULL;
9826   GtkWidget *content_area, *action_area;
9827   GtkWidget *label;
9828   GtkWidget *button;
9829   GtkWidget *entry;
9830   GtkWidget *vbox;
9831   static GdkColor red =    { 0, 0xffff, 0,      0      };
9832   static GdkColor green =  { 0, 0,      0xffff, 0      };
9833   static GdkColor blue =   { 0, 0,      0,      0xffff };
9834   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
9835   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
9836   PangoFontDescription *font_desc;
9837
9838   GtkRcStyle *rc_style;
9839
9840   if (!window)
9841     {
9842       window = gtk_dialog_new ();
9843       gtk_window_set_screen (GTK_WINDOW (window),
9844                              gtk_widget_get_screen (widget));
9845      
9846       g_signal_connect (window, "destroy",
9847                         G_CALLBACK (gtk_widget_destroyed),
9848                         &window);
9849
9850       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9851       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9852
9853       button = gtk_button_new_with_label ("Close");
9854       g_signal_connect_swapped (button, "clicked",
9855                                 G_CALLBACK (gtk_widget_destroy),
9856                                 window);
9857       gtk_widget_set_can_default (button, TRUE);
9858       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9859       gtk_widget_show (button);
9860
9861       vbox = gtk_vbox_new (FALSE, 5);
9862       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9863       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
9864       
9865       label = gtk_label_new ("Font:");
9866       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9867       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9868
9869       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
9870
9871       button = gtk_button_new_with_label ("Some Text");
9872       gtk_widget_modify_font (gtk_bin_get_child (GTK_BIN (button)),
9873                               font_desc);
9874       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9875
9876       label = gtk_label_new ("Foreground:");
9877       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9878       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9879
9880       button = gtk_button_new_with_label ("Some Text");
9881       gtk_widget_modify_fg (gtk_bin_get_child (GTK_BIN (button)),
9882                             GTK_STATE_NORMAL, &red);
9883       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9884
9885       label = gtk_label_new ("Background:");
9886       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9887       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9888
9889       button = gtk_button_new_with_label ("Some Text");
9890       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
9891       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9892
9893       label = gtk_label_new ("Text:");
9894       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9895       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9896
9897       entry = gtk_entry_new ();
9898       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9899       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
9900       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9901
9902       label = gtk_label_new ("Base:");
9903       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9904       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9905
9906       entry = gtk_entry_new ();
9907       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9908       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
9909       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9910
9911       label = gtk_label_new ("Cursor:");
9912       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9913       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9914
9915       entry = gtk_entry_new ();
9916       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9917       gtk_widget_modify_cursor (entry, &red, &red);
9918       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9919
9920       label = gtk_label_new ("Multiple:");
9921       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9922       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9923
9924       button = gtk_button_new_with_label ("Some Text");
9925
9926       rc_style = gtk_rc_style_new ();
9927
9928       rc_style->font_desc = pango_font_description_copy (font_desc);
9929       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
9930       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
9931       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
9932       rc_style->fg[GTK_STATE_NORMAL] = yellow;
9933       rc_style->bg[GTK_STATE_NORMAL] = blue;
9934       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
9935       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
9936       rc_style->fg[GTK_STATE_ACTIVE] = red;
9937       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
9938       rc_style->xthickness = 5;
9939       rc_style->ythickness = 5;
9940
9941       gtk_widget_modify_style (button, rc_style);
9942       gtk_widget_modify_style (gtk_bin_get_child (GTK_BIN (button)), rc_style);
9943
9944       g_object_unref (rc_style);
9945       
9946       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9947     }
9948   
9949   if (!gtk_widget_get_visible (window))
9950     gtk_widget_show_all (window);
9951   else
9952     gtk_widget_destroy (window);
9953 }
9954
9955 /*
9956  * Main Window and Exit
9957  */
9958
9959 void
9960 do_exit (GtkWidget *widget, GtkWidget *window)
9961 {
9962   gtk_widget_destroy (window);
9963   gtk_main_quit ();
9964 }
9965
9966 struct {
9967   char *label;
9968   void (*func) (GtkWidget *widget);
9969   gboolean do_not_benchmark;
9970 } buttons[] =
9971 {
9972   { "alpha window", create_alpha_window },
9973   { "big windows", create_big_windows },
9974   { "button box", create_button_box },
9975   { "buttons", create_buttons },
9976   { "check buttons", create_check_buttons },
9977   { "color selection", create_color_selection },
9978   { "composited window", create_composited_window },
9979   { "cursors", create_cursors },
9980   { "dialog", create_dialog },
9981   { "display & screen", create_display_screen, TRUE },
9982   { "entry", create_entry },
9983   { "event box", create_event_box },
9984   { "event watcher", create_event_watcher },
9985   { "expander", create_expander },
9986   { "flipping", create_flipping },
9987   { "focus", create_focus },
9988   { "font selection", create_font_selection },
9989   { "handle box", create_handle_box },
9990   { "image", create_image },
9991   { "key lookup", create_key_lookup },
9992   { "labels", create_labels },
9993   { "layout", create_layout },
9994   { "menus", create_menus },
9995   { "message dialog", create_message_dialog },
9996   { "modal window", create_modal_window, TRUE },
9997   { "notebook", create_notebook },
9998   { "panes", create_panes },
9999   { "paned keyboard", create_paned_keyboard_navigation },
10000   { "pixbuf", create_pixbuf },
10001   { "progress bar", create_progress_bar },
10002   { "properties", create_properties },
10003   { "radio buttons", create_radio_buttons },
10004   { "range controls", create_range_controls },
10005   { "rc file", create_rc_file },
10006   { "reparent", create_reparent },
10007   { "resize grips", create_resize_grips },
10008   { "rotated label", create_rotated_label },
10009   { "rotated text", create_rotated_text },
10010   { "rulers", create_rulers },
10011   { "saved position", create_saved_position },
10012   { "scrolled windows", create_scrolled_windows },
10013   { "shapes", create_shapes },
10014   { "size groups", create_size_groups },
10015   { "snapshot", create_snapshot },
10016   { "spinbutton", create_spins },
10017   { "statusbar", create_statusbar },
10018   { "styles", create_styles },
10019   { "test idle", create_idle_test },
10020   { "test mainloop", create_mainloop, TRUE },
10021   { "test scrolling", create_scroll_test },
10022   { "test selection", create_selection_test },
10023   { "test timeout", create_timeout_test },
10024   { "toggle buttons", create_toggle_buttons },
10025   { "toolbar", create_toolbar },
10026   { "tooltips", create_tooltips },
10027   { "WM hints", create_wmhints },
10028   { "window sizing", create_window_sizing },
10029   { "window states", create_window_states }
10030 };
10031 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
10032
10033 void
10034 create_main_window (void)
10035 {
10036   GtkWidget *window;
10037   GtkWidget *box1;
10038   GtkWidget *box2;
10039   GtkWidget *scrolled_window;
10040   GtkWidget *button;
10041   GtkWidget *label;
10042   gchar buffer[64];
10043   GtkWidget *separator;
10044   GdkGeometry geometry;
10045   int i;
10046
10047   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10048   gtk_widget_set_name (window, "main window");
10049   gtk_window_move (GTK_WINDOW (window), 50, 20);
10050   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
10051
10052   geometry.min_width = -1;
10053   geometry.min_height = -1;
10054   geometry.max_width = -1;
10055   geometry.max_height = G_MAXSHORT;
10056   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
10057                                  &geometry,
10058                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
10059
10060   g_signal_connect (window, "destroy",
10061                     G_CALLBACK (gtk_main_quit),
10062                     NULL);
10063   g_signal_connect (window, "delete-event",
10064                     G_CALLBACK (gtk_false),
10065                     NULL);
10066
10067   box1 = gtk_vbox_new (FALSE, 0);
10068   gtk_container_add (GTK_CONTAINER (window), box1);
10069
10070   if (gtk_micro_version > 0)
10071     sprintf (buffer,
10072              "Gtk+ v%d.%d.%d",
10073              gtk_get_major_version (),
10074              gtk_get_minor_version (),
10075              gtk_get_micro_version ());
10076   else
10077     sprintf (buffer,
10078              "Gtk+ v%d.%d",
10079              gtk_get_major_version (),
10080              gtk_get_minor_version ());
10081
10082   label = gtk_label_new (buffer);
10083   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
10084   gtk_widget_set_name (label, "testgtk-version-label");
10085
10086   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
10087   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
10088   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
10089                                   GTK_POLICY_NEVER, 
10090                                   GTK_POLICY_AUTOMATIC);
10091   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
10092
10093   box2 = gtk_vbox_new (FALSE, 0);
10094   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10095   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
10096   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
10097                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
10098   gtk_widget_show (box2);
10099
10100   for (i = 0; i < nbuttons; i++)
10101     {
10102       button = gtk_button_new_with_label (buttons[i].label);
10103       if (buttons[i].func)
10104         g_signal_connect (button, 
10105                           "clicked", 
10106                           G_CALLBACK(buttons[i].func),
10107                           NULL);
10108       else
10109         gtk_widget_set_sensitive (button, FALSE);
10110       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10111     }
10112
10113   separator = gtk_hseparator_new ();
10114   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
10115
10116   box2 = gtk_vbox_new (FALSE, 10);
10117   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10118   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
10119
10120   button = gtk_button_new_with_mnemonic ("_Close");
10121   g_signal_connect (button, "clicked",
10122                     G_CALLBACK (do_exit),
10123                     window);
10124   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10125   gtk_widget_set_can_default (button, TRUE);
10126   gtk_widget_grab_default (button);
10127
10128   gtk_widget_show_all (window);
10129 }
10130
10131 static void
10132 test_init (void)
10133 {
10134   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
10135                    G_FILE_TEST_EXISTS))
10136     {
10137       g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/loaders.cache", TRUE);
10138       g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
10139     }
10140 }
10141
10142 static char *
10143 pad (const char *str, int to)
10144 {
10145   static char buf[256];
10146   int len = strlen (str);
10147   int i;
10148
10149   for (i = 0; i < to; i++)
10150     buf[i] = ' ';
10151
10152   buf[to] = '\0';
10153
10154   memcpy (buf, str, len);
10155
10156   return buf;
10157 }
10158
10159 static void
10160 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
10161 {
10162   fn (widget); /* on */
10163   while (g_main_context_iteration (NULL, FALSE));
10164   fn (widget); /* off */
10165   while (g_main_context_iteration (NULL, FALSE));
10166 }
10167
10168 void
10169 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
10170 {
10171   GTimeVal tv0, tv1;
10172   double dt_first;
10173   double dt;
10174   int n;
10175   static gboolean printed_headers = FALSE;
10176
10177   if (!printed_headers) {
10178     g_print ("Test                 Iters      First      Other\n");
10179     g_print ("-------------------- ----- ---------- ----------\n");
10180     printed_headers = TRUE;
10181   }
10182
10183   g_get_current_time (&tv0);
10184   bench_iteration (widget, fn); 
10185   g_get_current_time (&tv1);
10186
10187   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10188         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10189
10190   g_get_current_time (&tv0);
10191   for (n = 0; n < num - 1; n++)
10192     bench_iteration (widget, fn); 
10193   g_get_current_time (&tv1);
10194   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10195         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10196
10197   g_print ("%s %5d ", pad (name, 20), num);
10198   if (num > 1)
10199     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
10200   else
10201     g_print ("%10.1f\n", dt_first);
10202 }
10203
10204 void
10205 do_bench (char* what, int num)
10206 {
10207   int i;
10208   GtkWidget *widget;
10209   void (* fn) (GtkWidget *widget);
10210   fn = NULL;
10211   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10212
10213   if (g_ascii_strcasecmp (what, "ALL") == 0)
10214     {
10215       for (i = 0; i < nbuttons; i++)
10216         {
10217           if (!buttons[i].do_not_benchmark)
10218             do_real_bench (widget, buttons[i].func, buttons[i].label, num);
10219         }
10220
10221       return;
10222     }
10223   else
10224     {
10225       for (i = 0; i < nbuttons; i++)
10226         {
10227           if (strcmp (buttons[i].label, what) == 0)
10228             {
10229               fn = buttons[i].func;
10230               break;
10231             }
10232         }
10233       
10234       if (!fn)
10235         g_print ("Can't bench: \"%s\" not found.\n", what);
10236       else
10237         do_real_bench (widget, fn, buttons[i].label, num);
10238     }
10239 }
10240
10241 void 
10242 usage (void)
10243 {
10244   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
10245   exit (1);
10246 }
10247
10248 int
10249 main (int argc, char *argv[])
10250 {
10251   GtkBindingSet *binding_set;
10252   int i;
10253   gboolean done_benchmarks = FALSE;
10254
10255   srand (time (NULL));
10256
10257   test_init ();
10258
10259   /* Check to see if we are being run from the correct
10260    * directory.
10261    */
10262   if (file_exists ("testgtkrc"))
10263     gtk_rc_add_default_file ("testgtkrc");
10264   else if (file_exists ("tests/testgtkrc"))
10265     gtk_rc_add_default_file ("tests/testgtkrc");
10266   else
10267     g_warning ("Couldn't find file \"testgtkrc\".");
10268
10269   g_set_application_name ("GTK+ Test Program");
10270
10271   gtk_init (&argc, &argv);
10272
10273   gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
10274                                         GDK_CONTROL_MASK |
10275                                         GDK_MOD1_MASK | 
10276                                         GDK_META_MASK |
10277                                         GDK_SUPER_MASK |
10278                                         GDK_HYPER_MASK |
10279                                         GDK_MOD4_MASK);
10280   /*  benchmarking
10281    */
10282   for (i = 1; i < argc; i++)
10283     {
10284       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
10285         {
10286           int num = 1;
10287           char *nextarg;
10288           char *what;
10289           char *count;
10290           
10291           nextarg = strchr (argv[i], '=');
10292           if (nextarg)
10293             nextarg++;
10294           else
10295             {
10296               i++;
10297               if (i == argc)
10298                 usage ();
10299               nextarg = argv[i];
10300             }
10301
10302           count = strchr (nextarg, ':');
10303           if (count)
10304             {
10305               what = g_strndup (nextarg, count - nextarg);
10306               count++;
10307               num = atoi (count);
10308               if (num <= 0)
10309                 usage ();
10310             }
10311           else
10312             what = g_strdup (nextarg);
10313
10314           do_bench (what, num ? num : 1);
10315           done_benchmarks = TRUE;
10316         }
10317       else
10318         usage ();
10319     }
10320   if (done_benchmarks)
10321     return 0;
10322
10323   /* bindings test
10324    */
10325   binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_WIDGET));
10326   gtk_binding_entry_add_signal (binding_set,
10327                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
10328                                 "debug_msg",
10329                                 1,
10330                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
10331   
10332   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
10333    * changes
10334    */
10335
10336   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
10337                        "   fg[NORMAL] = \"#ff0000\"\n"
10338                        "   font = \"Sans 18\"\n"
10339                        "}\n"
10340                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
10341   
10342   create_main_window ();
10343
10344   gtk_main ();
10345
10346   if (1)
10347     {
10348       while (g_main_context_pending (NULL))
10349         g_main_context_iteration (NULL, FALSE);
10350 #if 0
10351       sleep (1);
10352       while (g_main_context_pending (NULL))
10353         g_main_context_iteration (NULL, FALSE);
10354 #endif
10355     }
10356   return 0;
10357 }