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