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