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