]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
9586169749c2d96b6788b16671b41fb6a504cca9
[~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 font_selection_ok (GtkWidget              *w,
5435                    GtkFontSelectionDialog *fs)
5436 {
5437   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
5438
5439   g_print ("%s\n", s);
5440   g_free (s);
5441   gtk_widget_destroy (GTK_WIDGET (fs));
5442 }
5443
5444 void
5445 create_font_selection (GtkWidget *widget)
5446 {
5447   static GtkWidget *window = NULL;
5448
5449   if (!window)
5450     {
5451       GtkWidget *picker;
5452       GtkWidget *hbox;
5453       GtkWidget *label;
5454       
5455       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5456       gtk_window_set_screen (GTK_WINDOW (window),
5457                              gtk_widget_get_screen (widget));
5458
5459       g_signal_connect (window, "destroy",
5460                         G_CALLBACK (gtk_widget_destroyed),
5461                         &window);
5462
5463       gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
5464       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5465
5466       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
5467       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5468       gtk_container_add (GTK_CONTAINER (window), hbox);
5469       
5470       label = gtk_label_new ("Pick a font");
5471       gtk_container_add (GTK_CONTAINER (hbox), label);
5472
5473       picker = gtk_font_button_new ();
5474       gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
5475       gtk_container_add (GTK_CONTAINER (hbox), picker);
5476     }
5477   
5478   if (!gtk_widget_get_visible (window))
5479     gtk_widget_show_all (window);
5480   else
5481     gtk_widget_destroy (window);
5482 }
5483
5484 /*
5485  * GtkDialog
5486  */
5487
5488 static GtkWidget *dialog_window = NULL;
5489
5490 static void
5491 label_toggle (GtkWidget  *widget,
5492               GtkWidget **label)
5493 {
5494   if (!(*label))
5495     {
5496       *label = gtk_label_new ("Dialog Test");
5497       g_signal_connect (*label,
5498                         "destroy",
5499                         G_CALLBACK (gtk_widget_destroyed),
5500                         label);
5501       g_object_set (*label, "margin", 10, NULL);
5502       gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog_window))),
5503                           *label, TRUE, TRUE, 0);
5504       gtk_widget_show (*label);
5505     }
5506   else
5507     gtk_widget_destroy (*label);
5508 }
5509
5510 static void
5511 create_dialog (GtkWidget *widget)
5512 {
5513   static GtkWidget *label;
5514   GtkWidget *action_area;
5515   GtkWidget *button;
5516
5517   if (!dialog_window)
5518     {
5519       /* This is a terrible example; it's much simpler to create
5520        * dialogs than this. Don't use testgtk for example code,
5521        * use gtk-demo ;-)
5522        */
5523       
5524       dialog_window = gtk_dialog_new ();
5525       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5526                              gtk_widget_get_screen (widget));
5527
5528       g_signal_connect (dialog_window, "destroy",
5529                         G_CALLBACK (gtk_widget_destroyed),
5530                         &dialog_window);
5531
5532       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5533
5534       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5535       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5536
5537       button = gtk_button_new_with_label ("OK");
5538       gtk_widget_set_can_default (button, TRUE);
5539       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5540       gtk_widget_grab_default (button);
5541       gtk_widget_show (button);
5542
5543       button = gtk_button_new_with_label ("Toggle");
5544       g_signal_connect (button, "clicked",
5545                         G_CALLBACK (label_toggle),
5546                         &label);
5547       gtk_widget_set_can_default (button, TRUE);
5548       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5549       gtk_widget_show (button);
5550
5551       label = NULL;
5552     }
5553
5554   if (!gtk_widget_get_visible (dialog_window))
5555     gtk_widget_show (dialog_window);
5556   else
5557     gtk_widget_destroy (dialog_window);
5558 }
5559
5560 /* Display & Screen test 
5561  */
5562
5563 typedef struct
5564 {
5565   GtkWidget *combo;
5566   GtkWidget *entry;
5567   GtkWidget *radio_dpy;
5568   GtkWidget *toplevel;
5569   GtkWidget *dialog_window;
5570 } ScreenDisplaySelection;
5571
5572 static void
5573 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
5574 {
5575   const gchar *display_name;
5576   GdkDisplay *display = gtk_widget_get_display (widget);
5577   GtkWidget *dialog;
5578   GdkScreen *new_screen = NULL;
5579   GdkScreen *current_screen = gtk_widget_get_screen (widget);
5580   
5581   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
5582     {
5583       display_name = gtk_entry_get_text (GTK_ENTRY (data->entry));
5584       display = gdk_display_open (display_name);
5585       
5586       if (!display)
5587         {
5588           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
5589                                            GTK_DIALOG_DESTROY_WITH_PARENT,
5590                                            GTK_MESSAGE_ERROR,
5591                                            GTK_BUTTONS_OK,
5592                                            "The display :\n%s\ncannot be opened",
5593                                            display_name);
5594           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
5595           gtk_widget_show (dialog);
5596           g_signal_connect (dialog, "response",
5597                             G_CALLBACK (gtk_widget_destroy),
5598                             NULL);
5599         }
5600       else
5601         {
5602           GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
5603           gint i = 0;
5604           GtkTreeIter iter;
5605           gboolean found = FALSE;
5606           while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
5607             {
5608               gchar *name;
5609               gtk_tree_model_get (model, &iter, 0, &name, -1);
5610               found = !g_ascii_strcasecmp (display_name, name);
5611               g_free (name);
5612
5613               if (found)
5614                 break;
5615             }
5616           if (!found)
5617             gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (data->combo), display_name);
5618           new_screen = gdk_display_get_default_screen (display);
5619         }
5620     }
5621   else
5622     {
5623       gint number_of_screens = gdk_display_get_n_screens (display);
5624       gint screen_num = gdk_screen_get_number (current_screen);
5625       if ((screen_num +1) < number_of_screens)
5626         new_screen = gdk_display_get_screen (display, screen_num + 1);
5627       else
5628         new_screen = gdk_display_get_screen (display, 0);
5629     }
5630   
5631   if (new_screen) 
5632     {
5633       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
5634       gtk_widget_destroy (data->dialog_window);
5635     }
5636 }
5637
5638 void
5639 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
5640 {
5641   gtk_widget_destroy (data);
5642 }
5643
5644 void
5645 create_display_screen (GtkWidget *widget)
5646 {
5647   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
5648   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
5649   GtkWidget *bbox;
5650   ScreenDisplaySelection *scr_dpy_data;
5651   GdkScreen *screen = gtk_widget_get_screen (widget);
5652   GdkDisplay *display = gdk_screen_get_display (screen);
5653
5654   window = g_object_new (gtk_window_get_type (),
5655                            "screen", screen,
5656                            "user_data", NULL,
5657                            "type", GTK_WINDOW_TOPLEVEL,
5658                            "title",
5659                            "Screen or Display selection",
5660                            "border_width", 10, NULL);
5661   g_signal_connect (window, "destroy", 
5662                     G_CALLBACK (gtk_widget_destroy), NULL);
5663
5664   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
5665   gtk_container_add (GTK_CONTAINER (window), vbox);
5666   
5667   frame = gtk_frame_new ("Select screen or display");
5668   gtk_container_add (GTK_CONTAINER (vbox), frame);
5669   
5670   table = gtk_table_new (2, 2, TRUE);
5671   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
5672   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
5673
5674   gtk_container_add (GTK_CONTAINER (frame), table);
5675
5676   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
5677   if (gdk_display_get_n_screens(display) > 1)
5678     radio_scr = gtk_radio_button_new_with_label 
5679     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
5680   else
5681     {    
5682       radio_scr = gtk_radio_button_new_with_label 
5683         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
5684          "only one screen on the current display");
5685       gtk_widget_set_sensitive (radio_scr, FALSE);
5686     }
5687   combo_dpy = gtk_combo_box_text_new_with_entry ();
5688   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_dpy), "diabolo:0.0");
5689   gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_dpy))),
5690                       "<hostname>:<X Server Num>.<Screen Num>");
5691
5692   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
5693   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
5694   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
5695
5696   bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
5697   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
5698   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
5699   
5700   gtk_container_add (GTK_CONTAINER (vbox), bbox);
5701
5702   gtk_container_add (GTK_CONTAINER (bbox), applyb);
5703   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
5704
5705   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
5706
5707   scr_dpy_data->entry = gtk_bin_get_child (GTK_BIN (combo_dpy));
5708   scr_dpy_data->radio_dpy = radio_dpy;
5709   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
5710   scr_dpy_data->dialog_window = window;
5711
5712   g_signal_connect (cancelb, "clicked", 
5713                     G_CALLBACK (screen_display_destroy_diag), window);
5714   g_signal_connect (applyb, "clicked", 
5715                     G_CALLBACK (screen_display_check), scr_dpy_data);
5716   gtk_widget_show_all (window);
5717 }
5718
5719 /* Event Watcher
5720  */
5721 static gulong event_watcher_enter_id = 0;
5722 static gulong event_watcher_leave_id = 0;
5723
5724 static gboolean
5725 event_watcher (GSignalInvocationHint *ihint,
5726                guint                  n_param_values,
5727                const GValue          *param_values,
5728                gpointer               data)
5729 {
5730   g_print ("Watch: \"%s\" emitted for %s\n",
5731            g_signal_name (ihint->signal_id),
5732            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
5733
5734   return TRUE;
5735 }
5736
5737 static void
5738 event_watcher_down (void)
5739 {
5740   if (event_watcher_enter_id)
5741     {
5742       guint signal_id;
5743
5744       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5745       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5746       event_watcher_enter_id = 0;
5747       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5748       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5749       event_watcher_leave_id = 0;
5750     }
5751 }
5752
5753 static void
5754 event_watcher_toggle (void)
5755 {
5756   if (event_watcher_enter_id)
5757     event_watcher_down ();
5758   else
5759     {
5760       guint signal_id;
5761
5762       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5763       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5764       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5765       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5766     }
5767 }
5768
5769 static void
5770 create_event_watcher (GtkWidget *widget)
5771 {
5772   GtkWidget *action_area, *content_area;
5773   GtkWidget *button;
5774
5775   if (!dialog_window)
5776     {
5777       dialog_window = gtk_dialog_new ();
5778       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5779                              gtk_widget_get_screen (widget));
5780
5781       g_signal_connect (dialog_window, "destroy",
5782                         G_CALLBACK (gtk_widget_destroyed),
5783                         &dialog_window);
5784       g_signal_connect (dialog_window, "destroy",
5785                         G_CALLBACK (event_watcher_down),
5786                         NULL);
5787
5788       content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5789       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5790
5791       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5792       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5793       gtk_widget_set_size_request (dialog_window, 200, 110);
5794
5795       button = gtk_toggle_button_new_with_label ("Activate Watch");
5796       g_signal_connect (button, "clicked",
5797                         G_CALLBACK (event_watcher_toggle),
5798                         NULL);
5799       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5800       gtk_box_pack_start (GTK_BOX (content_area), button, TRUE, TRUE, 0);
5801       gtk_widget_show (button);
5802
5803       button = gtk_button_new_with_label ("Close");
5804       g_signal_connect_swapped (button, "clicked",
5805                                 G_CALLBACK (gtk_widget_destroy),
5806                                 dialog_window);
5807       gtk_widget_set_can_default (button, TRUE);
5808       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5809       gtk_widget_grab_default (button);
5810       gtk_widget_show (button);
5811     }
5812
5813   if (!gtk_widget_get_visible (dialog_window))
5814     gtk_widget_show (dialog_window);
5815   else
5816     gtk_widget_destroy (dialog_window);
5817 }
5818
5819 /*
5820  * GtkRange
5821  */
5822
5823 static gchar*
5824 reformat_value (GtkScale *scale,
5825                 gdouble   value)
5826 {
5827   return g_strdup_printf ("-->%0.*g<--",
5828                           gtk_scale_get_digits (scale), value);
5829 }
5830
5831 static void
5832 create_range_controls (GtkWidget *widget)
5833 {
5834   static GtkWidget *window = NULL;
5835   GtkWidget *box1;
5836   GtkWidget *box2;
5837   GtkWidget *button;
5838   GtkWidget *scrollbar;
5839   GtkWidget *scale;
5840   GtkWidget *separator;
5841   GtkAdjustment *adjustment;
5842   GtkWidget *hbox;
5843
5844   if (!window)
5845     {
5846       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5847
5848       gtk_window_set_screen (GTK_WINDOW (window),
5849                              gtk_widget_get_screen (widget));
5850
5851       g_signal_connect (window, "destroy",
5852                         G_CALLBACK (gtk_widget_destroyed),
5853                         &window);
5854
5855       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5856       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5857
5858
5859       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
5860       gtk_container_add (GTK_CONTAINER (window), box1);
5861       gtk_widget_show (box1);
5862
5863
5864       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5865       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5866       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5867       gtk_widget_show (box2);
5868
5869
5870       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5871
5872       scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5873       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
5874       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5875       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5876       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5877       gtk_widget_show (scale);
5878
5879       scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5880       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5881       gtk_widget_show (scrollbar);
5882
5883       scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5884       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5885       g_signal_connect (scale,
5886                         "format_value",
5887                         G_CALLBACK (reformat_value),
5888                         NULL);
5889       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5890       gtk_widget_show (scale);
5891       
5892       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5893
5894       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5895       gtk_widget_set_size_request (scale, -1, 200);
5896       gtk_scale_set_digits (GTK_SCALE (scale), 2);
5897       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5898       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5899       gtk_widget_show (scale);
5900
5901       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5902       gtk_widget_set_size_request (scale, -1, 200);
5903       gtk_scale_set_digits (GTK_SCALE (scale), 2);
5904       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5905       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
5906       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5907       gtk_widget_show (scale);
5908
5909       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5910       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5911       g_signal_connect (scale,
5912                         "format_value",
5913                         G_CALLBACK (reformat_value),
5914                         NULL);
5915       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5916       gtk_widget_show (scale);
5917
5918       
5919       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
5920       gtk_widget_show (hbox);
5921       
5922       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5923       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5924       gtk_widget_show (separator);
5925
5926
5927       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5928       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5929       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5930       gtk_widget_show (box2);
5931
5932
5933       button = gtk_button_new_with_label ("close");
5934       g_signal_connect_swapped (button, "clicked",
5935                                 G_CALLBACK (gtk_widget_destroy),
5936                                 window);
5937       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5938       gtk_widget_set_can_default (button, TRUE);
5939       gtk_widget_grab_default (button);
5940       gtk_widget_show (button);
5941     }
5942
5943   if (!gtk_widget_get_visible (window))
5944     gtk_widget_show (window);
5945   else
5946     gtk_widget_destroy (window);
5947 }
5948
5949 struct {
5950   GdkColor color;
5951   gchar *name;
5952 } text_colors[] = {
5953  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5954  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5955  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5956  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5957  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
5958  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5959  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5960  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5961 };
5962
5963 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5964
5965 /*
5966  * GtkNotebook
5967  */
5968
5969 static const char * book_open_xpm[] = {
5970 "16 16 4 1",
5971 "       c None s None",
5972 ".      c black",
5973 "X      c #808080",
5974 "o      c white",
5975 "                ",
5976 "  ..            ",
5977 " .Xo.    ...    ",
5978 " .Xoo. ..oo.    ",
5979 " .Xooo.Xooo...  ",
5980 " .Xooo.oooo.X.  ",
5981 " .Xooo.Xooo.X.  ",
5982 " .Xooo.oooo.X.  ",
5983 " .Xooo.Xooo.X.  ",
5984 " .Xooo.oooo.X.  ",
5985 "  .Xoo.Xoo..X.  ",
5986 "   .Xo.o..ooX.  ",
5987 "    .X..XXXXX.  ",
5988 "    ..X.......  ",
5989 "     ..         ",
5990 "                "};
5991
5992 static const char * book_closed_xpm[] = {
5993 "16 16 6 1",
5994 "       c None s None",
5995 ".      c black",
5996 "X      c red",
5997 "o      c yellow",
5998 "O      c #808080",
5999 "#      c white",
6000 "                ",
6001 "       ..       ",
6002 "     ..XX.      ",
6003 "   ..XXXXX.     ",
6004 " ..XXXXXXXX.    ",
6005 ".ooXXXXXXXXX.   ",
6006 "..ooXXXXXXXXX.  ",
6007 ".X.ooXXXXXXXXX. ",
6008 ".XX.ooXXXXXX..  ",
6009 " .XX.ooXXX..#O  ",
6010 "  .XX.oo..##OO. ",
6011 "   .XX..##OO..  ",
6012 "    .X.#OO..    ",
6013 "     ..O..      ",
6014 "      ..        ",
6015 "                "};
6016
6017 GdkPixbuf *book_open;
6018 GdkPixbuf *book_closed;
6019 GtkWidget *sample_notebook;
6020
6021 static void
6022 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
6023 {
6024   GtkWidget *page_widget;
6025   GtkWidget *pixwid;
6026
6027   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
6028
6029   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
6030   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6031   
6032   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
6033   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
6034 }
6035
6036 static void
6037 page_switch (GtkWidget *widget, gpointer *page, gint page_num)
6038 {
6039   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
6040   gint old_page_num = gtk_notebook_get_current_page (notebook);
6041  
6042   if (page_num == old_page_num)
6043     return;
6044
6045   set_page_image (notebook, page_num, book_open);
6046
6047   if (old_page_num != -1)
6048     set_page_image (notebook, old_page_num, book_closed);
6049 }
6050
6051 static void
6052 tab_fill (GtkToggleButton *button, GtkWidget *child)
6053 {
6054   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6055                            "tab-fill", gtk_toggle_button_get_active (button),
6056                            NULL);
6057 }
6058
6059 static void
6060 tab_expand (GtkToggleButton *button, GtkWidget *child)
6061 {
6062   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6063                            "tab-expand", gtk_toggle_button_get_active (button),
6064                            NULL);
6065 }
6066
6067 static void
6068 create_pages (GtkNotebook *notebook, gint start, gint end)
6069 {
6070   GtkWidget *child = NULL;
6071   GtkWidget *button;
6072   GtkWidget *label;
6073   GtkWidget *hbox;
6074   GtkWidget *vbox;
6075   GtkWidget *label_box;
6076   GtkWidget *menu_box;
6077   GtkWidget *pixwid;
6078   gint i;
6079   char buffer[32];
6080   char accel_buffer[32];
6081
6082   for (i = start; i <= end; i++)
6083     {
6084       sprintf (buffer, "Page %d", i);
6085       sprintf (accel_buffer, "Page _%d", i);
6086
6087       child = gtk_frame_new (buffer);
6088       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
6089
6090       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6091       gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
6092       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
6093       gtk_container_add (GTK_CONTAINER (child), vbox);
6094
6095       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6096       gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
6097       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
6098
6099       button = gtk_check_button_new_with_label ("Fill Tab");
6100       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6101       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
6102       g_signal_connect (button, "toggled",
6103                         G_CALLBACK (tab_fill), child);
6104
6105       button = gtk_check_button_new_with_label ("Expand Tab");
6106       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6107       g_signal_connect (button, "toggled",
6108                         G_CALLBACK (tab_expand), child);
6109
6110       button = gtk_button_new_with_label ("Hide Page");
6111       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
6112       g_signal_connect_swapped (button, "clicked",
6113                                 G_CALLBACK (gtk_widget_hide),
6114                                 child);
6115
6116       gtk_widget_show_all (child);
6117
6118       label_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6119       pixwid = gtk_image_new_from_pixbuf (book_closed);
6120       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
6121                            
6122       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
6123       gtk_widget_set_margin_left (pixwid, 3);
6124       gtk_widget_set_margin_right (pixwid, 3);
6125       gtk_widget_set_margin_bottom (pixwid, 1);
6126       gtk_widget_set_margin_top (pixwid, 1);
6127       label = gtk_label_new_with_mnemonic (accel_buffer);
6128       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
6129       gtk_widget_show_all (label_box);
6130       
6131                                        
6132       menu_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6133       pixwid = gtk_image_new_from_pixbuf (book_closed);
6134       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
6135       
6136       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
6137       gtk_widget_set_margin_left (pixwid, 3);
6138       gtk_widget_set_margin_right (pixwid, 3);
6139       gtk_widget_set_margin_bottom (pixwid, 1);
6140       gtk_widget_set_margin_top (pixwid, 1);
6141       label = gtk_label_new (buffer);
6142       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
6143       gtk_widget_show_all (menu_box);
6144
6145       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
6146     }
6147 }
6148
6149 static void
6150 rotate_notebook (GtkButton   *button,
6151                  GtkNotebook *notebook)
6152 {
6153   gtk_notebook_set_tab_pos (notebook, (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
6154 }
6155
6156 static void
6157 show_all_pages (GtkButton   *button,
6158                 GtkNotebook *notebook)
6159 {  
6160   gtk_container_foreach (GTK_CONTAINER (notebook),
6161                          (GtkCallback) gtk_widget_show, NULL);
6162 }
6163
6164 static void
6165 notebook_type_changed (GtkWidget *optionmenu,
6166                        gpointer   data)
6167 {
6168   GtkNotebook *notebook;
6169   gint i, c;
6170
6171   enum {
6172     STANDARD,
6173     NOTABS,
6174     BORDERLESS,
6175     SCROLLABLE
6176   };
6177
6178   notebook = GTK_NOTEBOOK (data);
6179
6180   c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
6181
6182   switch (c)
6183     {
6184     case STANDARD:
6185       /* standard notebook */
6186       gtk_notebook_set_show_tabs (notebook, TRUE);
6187       gtk_notebook_set_show_border (notebook, TRUE);
6188       gtk_notebook_set_scrollable (notebook, FALSE);
6189       break;
6190
6191     case NOTABS:
6192       /* notabs notebook */
6193       gtk_notebook_set_show_tabs (notebook, FALSE);
6194       gtk_notebook_set_show_border (notebook, TRUE);
6195       break;
6196
6197     case BORDERLESS:
6198       /* borderless */
6199       gtk_notebook_set_show_tabs (notebook, FALSE);
6200       gtk_notebook_set_show_border (notebook, FALSE);
6201       break;
6202
6203     case SCROLLABLE:  
6204       /* scrollable */
6205       gtk_notebook_set_show_tabs (notebook, TRUE);
6206       gtk_notebook_set_show_border (notebook, TRUE);
6207       gtk_notebook_set_scrollable (notebook, TRUE);
6208       if (gtk_notebook_get_n_pages (notebook) == 5)
6209         create_pages (notebook, 6, 15);
6210
6211       return;
6212       break;
6213     }
6214
6215   if (gtk_notebook_get_n_pages (notebook) == 15)
6216     for (i = 0; i < 10; i++)
6217       gtk_notebook_remove_page (notebook, 5);
6218 }
6219
6220 static void
6221 notebook_popup (GtkToggleButton *button,
6222                 GtkNotebook     *notebook)
6223 {
6224   if (gtk_toggle_button_get_active (button))
6225     gtk_notebook_popup_enable (notebook);
6226   else
6227     gtk_notebook_popup_disable (notebook);
6228 }
6229
6230 static void
6231 create_notebook (GtkWidget *widget)
6232 {
6233   static GtkWidget *window = NULL;
6234   GtkWidget *box1;
6235   GtkWidget *box2;
6236   GtkWidget *button;
6237   GtkWidget *separator;
6238   GtkWidget *omenu;
6239   GtkWidget *label;
6240
6241   static gchar *items[] =
6242   {
6243     "Standard",
6244     "No tabs",
6245     "Borderless",
6246     "Scrollable"
6247   };
6248   
6249   if (!window)
6250     {
6251       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6252       gtk_window_set_screen (GTK_WINDOW (window),
6253                              gtk_widget_get_screen (widget));
6254
6255       g_signal_connect (window, "destroy",
6256                         G_CALLBACK (gtk_widget_destroyed),
6257                         &window);
6258
6259       gtk_window_set_title (GTK_WINDOW (window), "notebook");
6260       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6261
6262       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6263       gtk_container_add (GTK_CONTAINER (window), box1);
6264
6265       sample_notebook = gtk_notebook_new ();
6266       g_signal_connect (sample_notebook, "switch_page",
6267                         G_CALLBACK (page_switch), NULL);
6268       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6269       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6270       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6271
6272       gtk_widget_realize (sample_notebook);
6273
6274       if (!book_open)
6275         book_open = gdk_pixbuf_new_from_xpm_data (book_open_xpm);
6276                                                   
6277       if (!book_closed)
6278         book_closed = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
6279
6280       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6281
6282       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
6283       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6284       
6285       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
6286       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6287       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6288
6289       button = gtk_check_button_new_with_label ("popup menu");
6290       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6291       g_signal_connect (button, "clicked",
6292                         G_CALLBACK (notebook_popup),
6293                         sample_notebook);
6294
6295       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
6296       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6297       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6298
6299       label = gtk_label_new ("Notebook Style :");
6300       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6301
6302       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
6303                                  notebook_type_changed,
6304                                  sample_notebook);
6305       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6306
6307       button = gtk_button_new_with_label ("Show all Pages");
6308       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6309       g_signal_connect (button, "clicked",
6310                         G_CALLBACK (show_all_pages), sample_notebook);
6311
6312       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
6313       gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
6314       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6315       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6316
6317       button = gtk_button_new_with_label ("prev");
6318       g_signal_connect_swapped (button, "clicked",
6319                                 G_CALLBACK (gtk_notebook_prev_page),
6320                                 sample_notebook);
6321       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6322
6323       button = gtk_button_new_with_label ("next");
6324       g_signal_connect_swapped (button, "clicked",
6325                                 G_CALLBACK (gtk_notebook_next_page),
6326                                 sample_notebook);
6327       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6328
6329       button = gtk_button_new_with_label ("rotate");
6330       g_signal_connect (button, "clicked",
6331                         G_CALLBACK (rotate_notebook), sample_notebook);
6332       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6333
6334       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
6335       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6336
6337       button = gtk_button_new_with_label ("close");
6338       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6339       g_signal_connect_swapped (button, "clicked",
6340                                 G_CALLBACK (gtk_widget_destroy),
6341                                 window);
6342       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6343       gtk_widget_set_can_default (button, TRUE);
6344       gtk_widget_grab_default (button);
6345     }
6346
6347   if (!gtk_widget_get_visible (window))
6348     gtk_widget_show_all (window);
6349   else
6350     gtk_widget_destroy (window);
6351 }
6352
6353 /*
6354  * GtkPanes
6355  */
6356
6357 void
6358 toggle_resize (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, "resize", &value);
6364   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6365   gtk_container_child_set_property (container, child, "resize", &value);
6366 }
6367
6368 void
6369 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6370 {
6371   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6372   GValue value = { 0, };
6373   g_value_init (&value, G_TYPE_BOOLEAN);
6374   gtk_container_child_get_property (container, child, "shrink", &value);
6375   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6376   gtk_container_child_set_property (container, child, "shrink", &value);
6377 }
6378
6379 static void
6380 paned_props_clicked (GtkWidget *button,
6381                      GObject   *paned)
6382 {
6383   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
6384   
6385   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
6386 }
6387
6388 GtkWidget *
6389 create_pane_options (GtkPaned    *paned,
6390                      const gchar *frame_label,
6391                      const gchar *label1,
6392                      const gchar *label2)
6393 {
6394   GtkWidget *child1, *child2;
6395   GtkWidget *frame;
6396   GtkWidget *table;
6397   GtkWidget *label;
6398   GtkWidget *button;
6399   GtkWidget *check_button;
6400
6401   child1 = gtk_paned_get_child1 (paned);
6402   child2 = gtk_paned_get_child2 (paned);
6403
6404   frame = gtk_frame_new (frame_label);
6405   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6406   
6407   table = gtk_table_new (4, 2, 4);
6408   gtk_container_add (GTK_CONTAINER (frame), table);
6409   
6410   label = gtk_label_new (label1);
6411   gtk_table_attach_defaults (GTK_TABLE (table), label,
6412                              0, 1, 0, 1);
6413   
6414   check_button = gtk_check_button_new_with_label ("Resize");
6415   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6416                              0, 1, 1, 2);
6417   g_signal_connect (check_button, "toggled",
6418                     G_CALLBACK (toggle_resize),
6419                     child1);
6420
6421   check_button = gtk_check_button_new_with_label ("Shrink");
6422   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6423                              0, 1, 2, 3);
6424   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6425                                TRUE);
6426   g_signal_connect (check_button, "toggled",
6427                     G_CALLBACK (toggle_shrink),
6428                     child1);
6429
6430   label = gtk_label_new (label2);
6431   gtk_table_attach_defaults (GTK_TABLE (table), label,
6432                              1, 2, 0, 1);
6433   
6434   check_button = gtk_check_button_new_with_label ("Resize");
6435   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6436                              1, 2, 1, 2);
6437   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6438                                TRUE);
6439   g_signal_connect (check_button, "toggled",
6440                     G_CALLBACK (toggle_resize),
6441                     child2);
6442
6443   check_button = gtk_check_button_new_with_label ("Shrink");
6444   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6445                              1, 2, 2, 3);
6446   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6447                                TRUE);
6448   g_signal_connect (check_button, "toggled",
6449                     G_CALLBACK (toggle_shrink),
6450                     child2);
6451
6452   button = gtk_button_new_with_mnemonic ("_Properties");
6453   gtk_table_attach_defaults (GTK_TABLE (table), button,
6454                              0, 2, 3, 4);
6455   g_signal_connect (button, "clicked",
6456                     G_CALLBACK (paned_props_clicked),
6457                     paned);
6458
6459   return frame;
6460 }
6461
6462 void
6463 create_panes (GtkWidget *widget)
6464 {
6465   static GtkWidget *window = NULL;
6466   GtkWidget *frame;
6467   GtkWidget *hpaned;
6468   GtkWidget *vpaned;
6469   GtkWidget *button;
6470   GtkWidget *vbox;
6471
6472   if (!window)
6473     {
6474       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6475
6476       gtk_window_set_screen (GTK_WINDOW (window),
6477                              gtk_widget_get_screen (widget));
6478       
6479       g_signal_connect (window, "destroy",
6480                         G_CALLBACK (gtk_widget_destroyed),
6481                         &window);
6482
6483       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6484       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6485
6486       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6487       gtk_container_add (GTK_CONTAINER (window), vbox);
6488       
6489       vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6490       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6491       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6492
6493       hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6494       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6495
6496       frame = gtk_frame_new (NULL);
6497       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6498       gtk_widget_set_size_request (frame, 60, 60);
6499       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6500       
6501       button = gtk_button_new_with_label ("Hi there");
6502       gtk_container_add (GTK_CONTAINER(frame), button);
6503
6504       frame = gtk_frame_new (NULL);
6505       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6506       gtk_widget_set_size_request (frame, 80, 60);
6507       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6508
6509       frame = gtk_frame_new (NULL);
6510       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6511       gtk_widget_set_size_request (frame, 60, 80);
6512       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6513
6514       /* Now create toggle buttons to control sizing */
6515
6516       gtk_box_pack_start (GTK_BOX (vbox),
6517                           create_pane_options (GTK_PANED (hpaned),
6518                                                "Horizontal",
6519                                                "Left",
6520                                                "Right"),
6521                           FALSE, FALSE, 0);
6522
6523       gtk_box_pack_start (GTK_BOX (vbox),
6524                           create_pane_options (GTK_PANED (vpaned),
6525                                                "Vertical",
6526                                                "Top",
6527                                                "Bottom"),
6528                           FALSE, FALSE, 0);
6529
6530       gtk_widget_show_all (vbox);
6531     }
6532
6533   if (!gtk_widget_get_visible (window))
6534     gtk_widget_show (window);
6535   else
6536     gtk_widget_destroy (window);
6537 }
6538
6539 /*
6540  * Paned keyboard navigation
6541  */
6542
6543 static GtkWidget*
6544 paned_keyboard_window1 (GtkWidget *widget)
6545 {
6546   GtkWidget *window1;
6547   GtkWidget *hpaned1;
6548   GtkWidget *frame1;
6549   GtkWidget *vbox1;
6550   GtkWidget *button7;
6551   GtkWidget *button8;
6552   GtkWidget *button9;
6553   GtkWidget *vpaned1;
6554   GtkWidget *frame2;
6555   GtkWidget *frame5;
6556   GtkWidget *hbox1;
6557   GtkWidget *button5;
6558   GtkWidget *button6;
6559   GtkWidget *frame3;
6560   GtkWidget *frame4;
6561   GtkWidget *table1;
6562   GtkWidget *button1;
6563   GtkWidget *button2;
6564   GtkWidget *button3;
6565   GtkWidget *button4;
6566
6567   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6568   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
6569   gtk_window_set_screen (GTK_WINDOW (window1), 
6570                          gtk_widget_get_screen (widget));
6571
6572   hpaned1 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6573   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
6574
6575   frame1 = gtk_frame_new (NULL);
6576   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
6577   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
6578
6579   vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6580   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
6581
6582   button7 = gtk_button_new_with_label ("button7");
6583   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
6584
6585   button8 = gtk_button_new_with_label ("button8");
6586   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
6587
6588   button9 = gtk_button_new_with_label ("button9");
6589   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
6590
6591   vpaned1 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6592   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
6593
6594   frame2 = gtk_frame_new (NULL);
6595   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
6596   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
6597
6598   frame5 = gtk_frame_new (NULL);
6599   gtk_container_add (GTK_CONTAINER (frame2), frame5);
6600
6601   hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6602   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
6603
6604   button5 = gtk_button_new_with_label ("button5");
6605   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
6606
6607   button6 = gtk_button_new_with_label ("button6");
6608   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
6609
6610   frame3 = gtk_frame_new (NULL);
6611   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
6612   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
6613
6614   frame4 = gtk_frame_new ("Buttons");
6615   gtk_container_add (GTK_CONTAINER (frame3), frame4);
6616   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
6617
6618   table1 = gtk_table_new (2, 2, FALSE);
6619   gtk_container_add (GTK_CONTAINER (frame4), table1);
6620   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
6621
6622   button1 = gtk_button_new_with_label ("button1");
6623   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
6624                     (GtkAttachOptions) (GTK_FILL),
6625                     (GtkAttachOptions) (0), 0, 0);
6626
6627   button2 = gtk_button_new_with_label ("button2");
6628   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
6629                     (GtkAttachOptions) (GTK_FILL),
6630                     (GtkAttachOptions) (0), 0, 0);
6631
6632   button3 = gtk_button_new_with_label ("button3");
6633   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
6634                     (GtkAttachOptions) (GTK_FILL),
6635                     (GtkAttachOptions) (0), 0, 0);
6636
6637   button4 = gtk_button_new_with_label ("button4");
6638   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
6639                     (GtkAttachOptions) (GTK_FILL),
6640                     (GtkAttachOptions) (0), 0, 0);
6641
6642   return window1;
6643 }
6644
6645 static GtkWidget*
6646 paned_keyboard_window2 (GtkWidget *widget)
6647 {
6648   GtkWidget *window2;
6649   GtkWidget *hpaned2;
6650   GtkWidget *frame6;
6651   GtkWidget *button13;
6652   GtkWidget *hbox2;
6653   GtkWidget *vpaned2;
6654   GtkWidget *frame7;
6655   GtkWidget *button12;
6656   GtkWidget *frame8;
6657   GtkWidget *button11;
6658   GtkWidget *button10;
6659
6660   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6661   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
6662
6663   gtk_window_set_screen (GTK_WINDOW (window2), 
6664                          gtk_widget_get_screen (widget));
6665
6666   hpaned2 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6667   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
6668
6669   frame6 = gtk_frame_new (NULL);
6670   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
6671   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
6672
6673   button13 = gtk_button_new_with_label ("button13");
6674   gtk_container_add (GTK_CONTAINER (frame6), button13);
6675
6676   hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6677   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
6678
6679   vpaned2 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6680   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
6681
6682   frame7 = gtk_frame_new (NULL);
6683   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
6684   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
6685
6686   button12 = gtk_button_new_with_label ("button12");
6687   gtk_container_add (GTK_CONTAINER (frame7), button12);
6688
6689   frame8 = gtk_frame_new (NULL);
6690   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
6691   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
6692
6693   button11 = gtk_button_new_with_label ("button11");
6694   gtk_container_add (GTK_CONTAINER (frame8), button11);
6695
6696   button10 = gtk_button_new_with_label ("button10");
6697   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
6698
6699   return window2;
6700 }
6701
6702 static GtkWidget*
6703 paned_keyboard_window3 (GtkWidget *widget)
6704 {
6705   GtkWidget *window3;
6706   GtkWidget *vbox2;
6707   GtkWidget *label1;
6708   GtkWidget *hpaned3;
6709   GtkWidget *frame9;
6710   GtkWidget *button14;
6711   GtkWidget *hpaned4;
6712   GtkWidget *frame10;
6713   GtkWidget *button15;
6714   GtkWidget *hpaned5;
6715   GtkWidget *frame11;
6716   GtkWidget *button16;
6717   GtkWidget *frame12;
6718   GtkWidget *button17;
6719
6720   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6721   g_object_set_data (G_OBJECT (window3), "window3", window3);
6722   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
6723
6724   gtk_window_set_screen (GTK_WINDOW (window3), 
6725                          gtk_widget_get_screen (widget));
6726   
6727
6728   vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6729   gtk_container_add (GTK_CONTAINER (window3), vbox2);
6730
6731   label1 = gtk_label_new ("Three panes nested inside each other");
6732   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
6733
6734   hpaned3 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6735   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
6736
6737   frame9 = gtk_frame_new (NULL);
6738   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
6739   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
6740
6741   button14 = gtk_button_new_with_label ("button14");
6742   gtk_container_add (GTK_CONTAINER (frame9), button14);
6743
6744   hpaned4 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6745   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
6746
6747   frame10 = gtk_frame_new (NULL);
6748   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
6749   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
6750
6751   button15 = gtk_button_new_with_label ("button15");
6752   gtk_container_add (GTK_CONTAINER (frame10), button15);
6753
6754   hpaned5 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6755   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
6756
6757   frame11 = gtk_frame_new (NULL);
6758   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
6759   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
6760
6761   button16 = gtk_button_new_with_label ("button16");
6762   gtk_container_add (GTK_CONTAINER (frame11), button16);
6763
6764   frame12 = gtk_frame_new (NULL);
6765   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
6766   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
6767
6768   button17 = gtk_button_new_with_label ("button17");
6769   gtk_container_add (GTK_CONTAINER (frame12), button17);
6770
6771   return window3;
6772 }
6773
6774 static GtkWidget*
6775 paned_keyboard_window4 (GtkWidget *widget)
6776 {
6777   GtkWidget *window4;
6778   GtkWidget *vbox3;
6779   GtkWidget *label2;
6780   GtkWidget *hpaned6;
6781   GtkWidget *vpaned3;
6782   GtkWidget *button19;
6783   GtkWidget *button18;
6784   GtkWidget *hbox3;
6785   GtkWidget *vpaned4;
6786   GtkWidget *button21;
6787   GtkWidget *button20;
6788   GtkWidget *vpaned5;
6789   GtkWidget *button23;
6790   GtkWidget *button22;
6791   GtkWidget *vpaned6;
6792   GtkWidget *button25;
6793   GtkWidget *button24;
6794
6795   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6796   g_object_set_data (G_OBJECT (window4), "window4", window4);
6797   gtk_window_set_title (GTK_WINDOW (window4), "window4");
6798
6799   gtk_window_set_screen (GTK_WINDOW (window4), 
6800                          gtk_widget_get_screen (widget));
6801
6802   vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6803   gtk_container_add (GTK_CONTAINER (window4), vbox3);
6804
6805   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
6806   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
6807   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
6808
6809   hpaned6 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6810   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
6811
6812   vpaned3 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6813   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
6814
6815   button19 = gtk_button_new_with_label ("button19");
6816   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
6817
6818   button18 = gtk_button_new_with_label ("button18");
6819   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
6820
6821   hbox3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6822   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
6823
6824   vpaned4 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6825   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
6826
6827   button21 = gtk_button_new_with_label ("button21");
6828   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
6829
6830   button20 = gtk_button_new_with_label ("button20");
6831   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
6832
6833   vpaned5 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6834   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
6835
6836   button23 = gtk_button_new_with_label ("button23");
6837   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
6838
6839   button22 = gtk_button_new_with_label ("button22");
6840   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
6841
6842   vpaned6 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6843   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
6844
6845   button25 = gtk_button_new_with_label ("button25");
6846   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
6847
6848   button24 = gtk_button_new_with_label ("button24");
6849   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
6850
6851   return window4;
6852 }
6853
6854 static void
6855 create_paned_keyboard_navigation (GtkWidget *widget)
6856 {
6857   static GtkWidget *window1 = NULL;
6858   static GtkWidget *window2 = NULL;
6859   static GtkWidget *window3 = NULL;
6860   static GtkWidget *window4 = NULL;
6861
6862   if (window1 && 
6863      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
6864     {
6865       gtk_widget_destroy (window1);
6866       gtk_widget_destroy (window2);
6867       gtk_widget_destroy (window3);
6868       gtk_widget_destroy (window4);
6869     }
6870   
6871   if (!window1)
6872     {
6873       window1 = paned_keyboard_window1 (widget);
6874       g_signal_connect (window1, "destroy",
6875                         G_CALLBACK (gtk_widget_destroyed),
6876                         &window1);
6877     }
6878
6879   if (!window2)
6880     {
6881       window2 = paned_keyboard_window2 (widget);
6882       g_signal_connect (window2, "destroy",
6883                         G_CALLBACK (gtk_widget_destroyed),
6884                         &window2);
6885     }
6886
6887   if (!window3)
6888     {
6889       window3 = paned_keyboard_window3 (widget);
6890       g_signal_connect (window3, "destroy",
6891                         G_CALLBACK (gtk_widget_destroyed),
6892                         &window3);
6893     }
6894
6895   if (!window4)
6896     {
6897       window4 = paned_keyboard_window4 (widget);
6898       g_signal_connect (window4, "destroy",
6899                         G_CALLBACK (gtk_widget_destroyed),
6900                         &window4);
6901     }
6902
6903   if (gtk_widget_get_visible (window1))
6904     gtk_widget_destroy (GTK_WIDGET (window1));
6905   else
6906     gtk_widget_show_all (GTK_WIDGET (window1));
6907
6908   if (gtk_widget_get_visible (window2))
6909     gtk_widget_destroy (GTK_WIDGET (window2));
6910   else
6911     gtk_widget_show_all (GTK_WIDGET (window2));
6912
6913   if (gtk_widget_get_visible (window3))
6914     gtk_widget_destroy (GTK_WIDGET (window3));
6915   else
6916     gtk_widget_show_all (GTK_WIDGET (window3));
6917
6918   if (gtk_widget_get_visible (window4))
6919     gtk_widget_destroy (GTK_WIDGET (window4));
6920   else
6921     gtk_widget_show_all (GTK_WIDGET (window4));
6922 }
6923
6924
6925 /*
6926  * Shaped Windows
6927  */
6928
6929 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6930
6931 static void
6932 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6933 {
6934   CursorOffset *p;
6935
6936   /* ignore double and triple click */
6937   if (event->type != GDK_BUTTON_PRESS)
6938     return;
6939
6940   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6941   p->x = (int) event->x;
6942   p->y = (int) event->y;
6943
6944   gtk_grab_add (widget);
6945   gdk_device_grab (gdk_event_get_device ((GdkEvent*)event),
6946                    gtk_widget_get_window (widget),
6947                    GDK_OWNERSHIP_NONE,
6948                    TRUE,
6949                    GDK_BUTTON_RELEASE_MASK |
6950                    GDK_BUTTON_MOTION_MASK |
6951                    GDK_POINTER_MOTION_HINT_MASK,
6952                    NULL,
6953                    event->time);
6954 }
6955
6956 static void
6957 shape_released (GtkWidget      *widget,
6958                 GdkEventButton *event)
6959 {
6960   gtk_grab_remove (widget);
6961   gdk_device_ungrab (gdk_event_get_device ((GdkEvent*)event), event->time);
6962 }
6963
6964 static void
6965 shape_motion (GtkWidget      *widget,
6966               GdkEventMotion *event)
6967 {
6968   gint xp, yp;
6969   CursorOffset * p;
6970   GdkModifierType mask;
6971
6972   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6973
6974   /*
6975    * Can't use event->x / event->y here 
6976    * because I need absolute coordinates.
6977    */
6978   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
6979   gtk_window_move (GTK_WINDOW (widget), xp  - p->x, yp  - p->y);
6980 }
6981
6982 GtkWidget *
6983 shape_create_icon (GdkScreen *screen,
6984                    char      *xpm_file,
6985                    gint       x,
6986                    gint       y,
6987                    gint       px,
6988                    gint       py,
6989                    gint       window_type)
6990 {
6991   GtkWidget *window;
6992   GtkWidget *image;
6993   GtkWidget *fixed;
6994   CursorOffset* icon_pos;
6995   cairo_surface_t *mask;
6996   cairo_region_t *mask_region;
6997   GdkPixbuf *pixbuf;
6998   cairo_t *cr;
6999
7000   /*
7001    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
7002    */
7003   window = gtk_window_new (window_type);
7004   gtk_window_set_screen (GTK_WINDOW (window), screen);
7005   
7006   fixed = gtk_fixed_new ();
7007   gtk_widget_set_size_request (fixed, 100, 100);
7008   gtk_container_add (GTK_CONTAINER (window), fixed);
7009   gtk_widget_show (fixed);
7010   
7011   gtk_widget_set_events (window, 
7012                          gtk_widget_get_events (window) |
7013                          GDK_BUTTON_MOTION_MASK |
7014                          GDK_POINTER_MOTION_HINT_MASK |
7015                          GDK_BUTTON_PRESS_MASK);
7016
7017   gtk_widget_realize (window);
7018
7019   pixbuf = gdk_pixbuf_new_from_file (xpm_file, NULL);
7020   g_assert (pixbuf); /* FIXME: error handling */
7021
7022   mask = cairo_image_surface_create (CAIRO_FORMAT_A1,
7023                                      gdk_pixbuf_get_width (pixbuf),
7024                                      gdk_pixbuf_get_height (pixbuf));
7025   cr = cairo_create (mask);
7026   gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
7027   cairo_paint (cr);
7028   cairo_destroy (cr);
7029
7030   mask_region = gdk_cairo_region_create_from_surface (mask);
7031                                                   
7032   cairo_region_translate (mask_region, px, py);
7033
7034   image = gtk_image_new_from_pixbuf (pixbuf);
7035   gtk_fixed_put (GTK_FIXED (fixed), image, px,py);
7036   gtk_widget_show (image);
7037   
7038   gtk_widget_shape_combine_region (window, mask_region);
7039   
7040   cairo_region_destroy (mask_region);
7041   cairo_surface_destroy (mask);
7042   g_object_unref (pixbuf);
7043
7044   g_signal_connect (window, "button_press_event",
7045                     G_CALLBACK (shape_pressed), NULL);
7046   g_signal_connect (window, "button_release_event",
7047                     G_CALLBACK (shape_released), NULL);
7048   g_signal_connect (window, "motion_notify_event",
7049                     G_CALLBACK (shape_motion), NULL);
7050
7051   icon_pos = g_new (CursorOffset, 1);
7052   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
7053
7054   gtk_window_move (GTK_WINDOW (window), x, y);
7055   gtk_widget_show (window);
7056   
7057   return window;
7058 }
7059
7060 void 
7061 create_shapes (GtkWidget *widget)
7062 {
7063   /* Variables used by the Drag/Drop and Shape Window demos */
7064   static GtkWidget *modeller = NULL;
7065   static GtkWidget *sheets = NULL;
7066   static GtkWidget *rings = NULL;
7067   static GtkWidget *with_region = NULL;
7068   GdkScreen *screen = gtk_widget_get_screen (widget);
7069   
7070   if (!(file_exists ("Modeller.xpm") &&
7071         file_exists ("FilesQueue.xpm") &&
7072         file_exists ("3DRings.xpm")))
7073     return;
7074   
7075
7076   if (!modeller)
7077     {
7078       modeller = shape_create_icon (screen, "Modeller.xpm",
7079                                     440, 140, 0,0, GTK_WINDOW_POPUP);
7080
7081       g_signal_connect (modeller, "destroy",
7082                         G_CALLBACK (gtk_widget_destroyed),
7083                         &modeller);
7084     }
7085   else
7086     gtk_widget_destroy (modeller);
7087
7088   if (!sheets)
7089     {
7090       sheets = shape_create_icon (screen, "FilesQueue.xpm",
7091                                   580, 170, 0,0, GTK_WINDOW_POPUP);
7092
7093       g_signal_connect (sheets, "destroy",
7094                         G_CALLBACK (gtk_widget_destroyed),
7095                         &sheets);
7096
7097     }
7098   else
7099     gtk_widget_destroy (sheets);
7100
7101   if (!rings)
7102     {
7103       rings = shape_create_icon (screen, "3DRings.xpm",
7104                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7105
7106       g_signal_connect (rings, "destroy",
7107                         G_CALLBACK (gtk_widget_destroyed),
7108                         &rings);
7109     }
7110   else
7111     gtk_widget_destroy (rings);
7112
7113   if (!with_region)
7114     {
7115       cairo_region_t *region;
7116       gint x, y;
7117       
7118       with_region = shape_create_icon (screen, "3DRings.xpm",
7119                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7120
7121       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
7122       
7123       g_signal_connect (with_region, "destroy",
7124                         G_CALLBACK (gtk_widget_destroyed),
7125                         &with_region);
7126
7127       /* reset shape from mask to a region */
7128       x = 0;
7129       y = 0;
7130       region = cairo_region_create ();
7131
7132       while (x < 460)
7133         {
7134           while (y < 270)
7135             {
7136               GdkRectangle rect;
7137               rect.x = x;
7138               rect.y = y;
7139               rect.width = 10;
7140               rect.height = 10;
7141
7142               cairo_region_union_rectangle (region, &rect);
7143               
7144               y += 20;
7145             }
7146           y = 0;
7147           x += 20;
7148         }
7149
7150       gdk_window_shape_combine_region (gtk_widget_get_window (with_region),
7151                                        region,
7152                                        0, 0);
7153     }
7154   else
7155     gtk_widget_destroy (with_region);
7156 }
7157
7158 /*
7159  * WM Hints demo
7160  */
7161
7162 void
7163 create_wmhints (GtkWidget *widget)
7164 {
7165   static GtkWidget *window = NULL;
7166   GtkWidget *label;
7167   GtkWidget *separator;
7168   GtkWidget *button;
7169   GtkWidget *box1;
7170   GtkWidget *box2;
7171   GdkWindow *gdk_window;
7172   GdkPixbuf *pixbuf;
7173   GList *list;
7174
7175   if (!window)
7176     {
7177       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7178
7179       gtk_window_set_screen (GTK_WINDOW (window),
7180                              gtk_widget_get_screen (widget));
7181       
7182       g_signal_connect (window, "destroy",
7183                         G_CALLBACK (gtk_widget_destroyed),
7184                         &window);
7185
7186       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
7187       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7188
7189       gtk_widget_realize (window);
7190
7191       gdk_window = gtk_widget_get_window (window);
7192
7193       pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
7194       list = g_list_prepend (NULL, pixbuf);
7195
7196       gdk_window_set_icon_list (gdk_window, list);
7197       
7198       g_list_free (list);
7199       g_object_unref (pixbuf);
7200
7201       gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
7202   
7203       gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL | GDK_DECOR_MENU);
7204       gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
7205       
7206       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7207       gtk_container_add (GTK_CONTAINER (window), box1);
7208       gtk_widget_show (box1);
7209
7210       label = gtk_label_new ("Try iconizing me!");
7211       gtk_widget_set_size_request (label, 150, 50);
7212       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
7213       gtk_widget_show (label);
7214
7215
7216       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
7217       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7218       gtk_widget_show (separator);
7219
7220
7221       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
7222       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7223       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7224       gtk_widget_show (box2);
7225
7226
7227       button = gtk_button_new_with_label ("close");
7228
7229       g_signal_connect_swapped (button, "clicked",
7230                                 G_CALLBACK (gtk_widget_destroy),
7231                                 window);
7232
7233       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7234       gtk_widget_set_can_default (button, TRUE);
7235       gtk_widget_grab_default (button);
7236       gtk_widget_show (button);
7237     }
7238
7239   if (!gtk_widget_get_visible (window))
7240     gtk_widget_show (window);
7241   else
7242     gtk_widget_destroy (window);
7243 }
7244
7245
7246 /*
7247  * Window state tracking
7248  */
7249
7250 static gint
7251 window_state_callback (GtkWidget *widget,
7252                        GdkEventWindowState *event,
7253                        gpointer data)
7254 {
7255   GtkWidget *label = data;
7256   gchar *msg;
7257
7258   msg = g_strconcat (gtk_window_get_title (GTK_WINDOW (widget)), ": ",
7259                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
7260                      "withdrawn" : "not withdrawn", ", ",
7261                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
7262                      "iconified" : "not iconified", ", ",
7263                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
7264                      "sticky" : "not sticky", ", ",
7265                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
7266                      "maximized" : "not maximized", ", ",
7267                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
7268                      "fullscreen" : "not fullscreen",
7269                      (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
7270                      "above" : "not above", ", ",
7271                      (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
7272                      "below" : "not below", ", ",
7273                      NULL);
7274   
7275   gtk_label_set_text (GTK_LABEL (label), msg);
7276
7277   g_free (msg);
7278
7279   return FALSE;
7280 }
7281
7282 static GtkWidget*
7283 tracking_label (GtkWidget *window)
7284 {
7285   GtkWidget *label;
7286   GtkWidget *hbox;
7287   GtkWidget *button;
7288
7289   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
7290
7291   g_signal_connect_object (hbox,
7292                            "destroy",
7293                            G_CALLBACK (gtk_widget_destroy),
7294                            window,
7295                            G_CONNECT_SWAPPED);
7296   
7297   label = gtk_label_new ("<no window state events received>");
7298   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
7299   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
7300   
7301   g_signal_connect (window,
7302                     "window_state_event",
7303                     G_CALLBACK (window_state_callback),
7304                     label);
7305
7306   button = gtk_button_new_with_label ("Deiconify");
7307   g_signal_connect_object (button,
7308                            "clicked",
7309                            G_CALLBACK (gtk_window_deiconify),
7310                            window,
7311                            G_CONNECT_SWAPPED);
7312   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7313
7314   button = gtk_button_new_with_label ("Iconify");
7315   g_signal_connect_object (button,
7316                            "clicked",
7317                            G_CALLBACK (gtk_window_iconify),
7318                            window,
7319                            G_CONNECT_SWAPPED);
7320   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7321
7322   button = gtk_button_new_with_label ("Fullscreen");
7323   g_signal_connect_object (button,
7324                            "clicked",
7325                            G_CALLBACK (gtk_window_fullscreen),
7326                            window,
7327                            G_CONNECT_SWAPPED);
7328   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7329
7330   button = gtk_button_new_with_label ("Unfullscreen");
7331   g_signal_connect_object (button,
7332                            "clicked",
7333                            G_CALLBACK (gtk_window_unfullscreen),
7334                            window,
7335                            G_CONNECT_SWAPPED);
7336   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7337   
7338   button = gtk_button_new_with_label ("Present");
7339   g_signal_connect_object (button,
7340                            "clicked",
7341                            G_CALLBACK (gtk_window_present),
7342                            window,
7343                            G_CONNECT_SWAPPED);
7344   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7345
7346   button = gtk_button_new_with_label ("Show");
7347   g_signal_connect_object (button,
7348                            "clicked",
7349                            G_CALLBACK (gtk_widget_show),
7350                            window,
7351                            G_CONNECT_SWAPPED);
7352   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7353   
7354   gtk_widget_show_all (hbox);
7355   
7356   return hbox;
7357 }
7358
7359 void
7360 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
7361 {
7362   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7363
7364   gtk_window_set_keep_above (GTK_WINDOW (data),
7365                              gtk_toggle_button_get_active (togglebutton));
7366
7367   if (gtk_toggle_button_get_active (togglebutton))
7368     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7369 }
7370
7371 void
7372 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
7373 {
7374   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7375
7376   gtk_window_set_keep_below (GTK_WINDOW (data),
7377                              gtk_toggle_button_get_active (togglebutton));
7378
7379   if (gtk_toggle_button_get_active (togglebutton))
7380     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7381 }
7382
7383
7384 static GtkWidget*
7385 get_state_controls (GtkWidget *window)
7386 {
7387   GtkWidget *vbox;
7388   GtkWidget *button;
7389   GtkWidget *button_above;
7390   GtkWidget *button_below;
7391
7392   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7393   
7394   button = gtk_button_new_with_label ("Stick");
7395   g_signal_connect_object (button,
7396                            "clicked",
7397                            G_CALLBACK (gtk_window_stick),
7398                            window,
7399                            G_CONNECT_SWAPPED);
7400   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7401
7402   button = gtk_button_new_with_label ("Unstick");
7403   g_signal_connect_object (button,
7404                            "clicked",
7405                            G_CALLBACK (gtk_window_unstick),
7406                            window,
7407                            G_CONNECT_SWAPPED);
7408   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7409   
7410   button = gtk_button_new_with_label ("Maximize");
7411   g_signal_connect_object (button,
7412                            "clicked",
7413                            G_CALLBACK (gtk_window_maximize),
7414                            window,
7415                            G_CONNECT_SWAPPED);
7416   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7417
7418   button = gtk_button_new_with_label ("Unmaximize");
7419   g_signal_connect_object (button,
7420                            "clicked",
7421                            G_CALLBACK (gtk_window_unmaximize),
7422                            window,
7423                            G_CONNECT_SWAPPED);
7424   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7425
7426   button = gtk_button_new_with_label ("Iconify");
7427   g_signal_connect_object (button,
7428                            "clicked",
7429                            G_CALLBACK (gtk_window_iconify),
7430                            window,
7431                            G_CONNECT_SWAPPED);
7432   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7433
7434   button = gtk_button_new_with_label ("Fullscreen");
7435   g_signal_connect_object (button,
7436                            "clicked",
7437                            G_CALLBACK (gtk_window_fullscreen),
7438                            window,
7439                            G_CONNECT_SWAPPED);
7440   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7441
7442   button = gtk_button_new_with_label ("Unfullscreen");
7443   g_signal_connect_object (button,
7444                            "clicked",
7445                            G_CALLBACK (gtk_window_unfullscreen),
7446                            window,
7447                            G_CONNECT_SWAPPED);
7448   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7449
7450   button_above = gtk_toggle_button_new_with_label ("Keep above");
7451   g_signal_connect (button_above,
7452                     "toggled",
7453                     G_CALLBACK (keep_window_above),
7454                     window);
7455   gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
7456
7457   button_below = gtk_toggle_button_new_with_label ("Keep below");
7458   g_signal_connect (button_below,
7459                     "toggled",
7460                     G_CALLBACK (keep_window_below),
7461                     window);
7462   gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
7463
7464   g_object_set_data (G_OBJECT (button_above), "radio", button_below);
7465   g_object_set_data (G_OBJECT (button_below), "radio", button_above);
7466
7467   button = gtk_button_new_with_label ("Hide (withdraw)");
7468   g_signal_connect_object (button,
7469                            "clicked",
7470                            G_CALLBACK (gtk_widget_hide),
7471                            window,
7472                            G_CONNECT_SWAPPED);
7473   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7474   
7475   gtk_widget_show_all (vbox);
7476
7477   return vbox;
7478 }
7479
7480 void
7481 create_window_states (GtkWidget *widget)
7482 {
7483   static GtkWidget *window = NULL;
7484   GtkWidget *label;
7485   GtkWidget *box1;
7486   GtkWidget *iconified;
7487   GtkWidget *normal;
7488   GtkWidget *controls;
7489
7490   if (!window)
7491     {
7492       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7493       gtk_window_set_screen (GTK_WINDOW (window),
7494                              gtk_widget_get_screen (widget));
7495
7496       g_signal_connect (window, "destroy",
7497                         G_CALLBACK (gtk_widget_destroyed),
7498                         &window);
7499
7500       gtk_window_set_title (GTK_WINDOW (window), "Window states");
7501       
7502       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7503       gtk_container_add (GTK_CONTAINER (window), box1);
7504
7505       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7506
7507       gtk_window_set_screen (GTK_WINDOW (iconified),
7508                              gtk_widget_get_screen (widget));
7509       
7510       g_signal_connect_object (iconified, "destroy",
7511                                G_CALLBACK (gtk_widget_destroy),
7512                                window,
7513                                G_CONNECT_SWAPPED);
7514       gtk_window_iconify (GTK_WINDOW (iconified));
7515       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
7516       controls = get_state_controls (iconified);
7517       gtk_container_add (GTK_CONTAINER (iconified), controls);
7518       
7519       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7520
7521       gtk_window_set_screen (GTK_WINDOW (normal),
7522                              gtk_widget_get_screen (widget));
7523       
7524       g_signal_connect_object (normal, "destroy",
7525                                G_CALLBACK (gtk_widget_destroy),
7526                                window,
7527                                G_CONNECT_SWAPPED);
7528       
7529       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
7530       controls = get_state_controls (normal);
7531       gtk_container_add (GTK_CONTAINER (normal), controls);
7532       
7533       label = tracking_label (iconified);
7534       gtk_container_add (GTK_CONTAINER (box1), label);
7535
7536       label = tracking_label (normal);
7537       gtk_container_add (GTK_CONTAINER (box1), label);
7538
7539       gtk_widget_show_all (iconified);
7540       gtk_widget_show_all (normal);
7541       gtk_widget_show_all (box1);
7542     }
7543
7544   if (!gtk_widget_get_visible (window))
7545     gtk_widget_show (window);
7546   else
7547     gtk_widget_destroy (window);
7548 }
7549
7550 /*
7551  * Window sizing
7552  */
7553
7554 static gint
7555 configure_event_callback (GtkWidget *widget,
7556                           GdkEventConfigure *event,
7557                           gpointer data)
7558 {
7559   GtkWidget *label = data;
7560   gchar *msg;
7561   gint x, y;
7562   
7563   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
7564   
7565   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
7566                          "position: %d, %d",
7567                          event->x, event->y, event->width, event->height,
7568                          x, y);
7569   
7570   gtk_label_set_text (GTK_LABEL (label), msg);
7571
7572   g_free (msg);
7573
7574   return FALSE;
7575 }
7576
7577 static void
7578 get_ints (GtkWidget *window,
7579           gint      *a,
7580           gint      *b)
7581 {
7582   GtkWidget *spin1;
7583   GtkWidget *spin2;
7584
7585   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
7586   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
7587
7588   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
7589   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7590 }
7591
7592 static void
7593 set_size_callback (GtkWidget *widget,
7594                    gpointer   data)
7595 {
7596   gint w, h;
7597   
7598   get_ints (data, &w, &h);
7599
7600   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
7601 }
7602
7603 static void
7604 unset_default_size_callback (GtkWidget *widget,
7605                              gpointer   data)
7606 {
7607   gtk_window_set_default_size (g_object_get_data (data, "target"),
7608                                -1, -1);
7609 }
7610
7611 static void
7612 set_default_size_callback (GtkWidget *widget,
7613                            gpointer   data)
7614 {
7615   gint w, h;
7616   
7617   get_ints (data, &w, &h);
7618
7619   gtk_window_set_default_size (g_object_get_data (data, "target"),
7620                                w, h);
7621 }
7622
7623 static void
7624 unset_size_request_callback (GtkWidget *widget,
7625                              gpointer   data)
7626 {
7627   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7628                                -1, -1);
7629 }
7630
7631 static void
7632 set_size_request_callback (GtkWidget *widget,
7633                            gpointer   data)
7634 {
7635   gint w, h;
7636   
7637   get_ints (data, &w, &h);
7638
7639   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7640                                w, h);
7641 }
7642
7643 static void
7644 set_location_callback (GtkWidget *widget,
7645                        gpointer   data)
7646 {
7647   gint x, y;
7648   
7649   get_ints (data, &x, &y);
7650
7651   gtk_window_move (g_object_get_data (data, "target"), x, y);
7652 }
7653
7654 static void
7655 move_to_position_callback (GtkWidget *widget,
7656                            gpointer   data)
7657 {
7658   gint x, y;
7659   GtkWindow *window;
7660
7661   window = g_object_get_data (data, "target");
7662   
7663   gtk_window_get_position (window, &x, &y);
7664
7665   gtk_window_move (window, x, y);
7666 }
7667
7668 static void
7669 set_geometry_callback (GtkWidget *entry,
7670                        gpointer   data)
7671 {
7672   gchar *text;
7673   GtkWindow *target;
7674
7675   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
7676   
7677   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
7678
7679   if (!gtk_window_parse_geometry (target, text))
7680     g_print ("Bad geometry string '%s'\n", text);
7681
7682   g_free (text);
7683 }
7684
7685 static void
7686 resizable_callback (GtkWidget *widget,
7687                      gpointer   data)
7688 {
7689   g_object_set (g_object_get_data (data, "target"),
7690                 "resizable", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
7691                 NULL);
7692 }
7693
7694 static void
7695 gravity_selected (GtkWidget *widget,
7696                   gpointer   data)
7697 {
7698   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
7699                           gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GDK_GRAVITY_NORTH_WEST);
7700 }
7701
7702 static void
7703 pos_selected (GtkWidget *widget,
7704               gpointer   data)
7705 {
7706   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
7707                            gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GTK_WIN_POS_NONE);
7708 }
7709
7710 static void
7711 move_gravity_window_to_current_position (GtkWidget *widget,
7712                                          gpointer   data)
7713 {
7714   gint x, y;
7715   GtkWindow *window;
7716
7717   window = GTK_WINDOW (data);    
7718   
7719   gtk_window_get_position (window, &x, &y);
7720
7721   gtk_window_move (window, x, y);
7722 }
7723
7724 static void
7725 get_screen_corner (GtkWindow *window,
7726                    gint      *x,
7727                    gint      *y)
7728 {
7729   int w, h;
7730   GdkScreen * screen = gtk_window_get_screen (window);
7731   
7732   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
7733
7734   switch (gtk_window_get_gravity (window))
7735     {
7736     case GDK_GRAVITY_SOUTH_EAST:
7737       *x = gdk_screen_get_width (screen) - w;
7738       *y = gdk_screen_get_height (screen) - h;
7739       break;
7740
7741     case GDK_GRAVITY_NORTH_EAST:
7742       *x = gdk_screen_get_width (screen) - w;
7743       *y = 0;
7744       break;
7745
7746     case GDK_GRAVITY_SOUTH_WEST:
7747       *x = 0;
7748       *y = gdk_screen_get_height (screen) - h;
7749       break;
7750
7751     case GDK_GRAVITY_NORTH_WEST:
7752       *x = 0;
7753       *y = 0;
7754       break;
7755       
7756     case GDK_GRAVITY_SOUTH:
7757       *x = (gdk_screen_get_width (screen) - w) / 2;
7758       *y = gdk_screen_get_height (screen) - h;
7759       break;
7760
7761     case GDK_GRAVITY_NORTH:
7762       *x = (gdk_screen_get_width (screen) - w) / 2;
7763       *y = 0;
7764       break;
7765
7766     case GDK_GRAVITY_WEST:
7767       *x = 0;
7768       *y = (gdk_screen_get_height (screen) - h) / 2;
7769       break;
7770
7771     case GDK_GRAVITY_EAST:
7772       *x = gdk_screen_get_width (screen) - w;
7773       *y = (gdk_screen_get_height (screen) - h) / 2;
7774       break;
7775
7776     case GDK_GRAVITY_CENTER:
7777       *x = (gdk_screen_get_width (screen) - w) / 2;
7778       *y = (gdk_screen_get_height (screen) - h) / 2;
7779       break;
7780
7781     case GDK_GRAVITY_STATIC:
7782       /* pick some random numbers */
7783       *x = 350;
7784       *y = 350;
7785       break;
7786
7787     default:
7788       g_assert_not_reached ();
7789       break;
7790     }
7791 }
7792
7793 static void
7794 move_gravity_window_to_starting_position (GtkWidget *widget,
7795                                           gpointer   data)
7796 {
7797   gint x, y;
7798   GtkWindow *window;
7799
7800   window = GTK_WINDOW (data);    
7801   
7802   get_screen_corner (window,
7803                      &x, &y);
7804   
7805   gtk_window_move (window, x, y);
7806 }
7807
7808 static GtkWidget*
7809 make_gravity_window (GtkWidget   *destroy_with,
7810                      GdkGravity   gravity,
7811                      const gchar *title)
7812 {
7813   GtkWidget *window;
7814   GtkWidget *button;
7815   GtkWidget *vbox;
7816   int x, y;
7817   
7818   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7819
7820   gtk_window_set_screen (GTK_WINDOW (window),
7821                          gtk_widget_get_screen (destroy_with));
7822
7823   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7824   gtk_widget_show (vbox);
7825   
7826   gtk_container_add (GTK_CONTAINER (window), vbox);
7827   gtk_window_set_title (GTK_WINDOW (window), title);
7828   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
7829
7830   g_signal_connect_object (destroy_with,
7831                            "destroy",
7832                            G_CALLBACK (gtk_widget_destroy),
7833                            window,
7834                            G_CONNECT_SWAPPED);
7835
7836   
7837   button = gtk_button_new_with_mnemonic ("_Move to current position");
7838
7839   g_signal_connect (button, "clicked",
7840                     G_CALLBACK (move_gravity_window_to_current_position),
7841                     window);
7842
7843   gtk_container_add (GTK_CONTAINER (vbox), button);
7844   gtk_widget_show (button);
7845
7846   button = gtk_button_new_with_mnemonic ("Move to _starting position");
7847
7848   g_signal_connect (button, "clicked",
7849                     G_CALLBACK (move_gravity_window_to_starting_position),
7850                     window);
7851
7852   gtk_container_add (GTK_CONTAINER (vbox), button);
7853   gtk_widget_show (button);
7854   
7855   /* Pretend this is the result of --geometry.
7856    * DO NOT COPY THIS CODE unless you are setting --geometry results,
7857    * and in that case you probably should just use gtk_window_parse_geometry().
7858    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
7859    * you are parsing --geometry or equivalent.
7860    */
7861   gtk_window_set_geometry_hints (GTK_WINDOW (window),
7862                                  NULL, NULL,
7863                                  GDK_HINT_USER_POS);
7864
7865   gtk_window_set_default_size (GTK_WINDOW (window),
7866                                200, 200);
7867
7868   get_screen_corner (GTK_WINDOW (window), &x, &y);
7869   
7870   gtk_window_move (GTK_WINDOW (window),
7871                    x, y);
7872   
7873   return window;
7874 }
7875
7876 static void
7877 do_gravity_test (GtkWidget *widget,
7878                  gpointer   data)
7879 {
7880   GtkWidget *destroy_with = data;
7881   GtkWidget *window;
7882   
7883   /* We put a window at each gravity point on the screen. */
7884   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
7885                                 "NorthWest");
7886   gtk_widget_show (window);
7887   
7888   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
7889                                 "SouthEast");
7890   gtk_widget_show (window);
7891
7892   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
7893                                 "NorthEast");
7894   gtk_widget_show (window);
7895
7896   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
7897                                 "SouthWest");
7898   gtk_widget_show (window);
7899
7900   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
7901                                 "South");
7902   gtk_widget_show (window);
7903
7904   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
7905                                 "North");
7906   gtk_widget_show (window);
7907
7908   
7909   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
7910                                 "West");
7911   gtk_widget_show (window);
7912
7913     
7914   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
7915                                 "East");
7916   gtk_widget_show (window);
7917
7918   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
7919                                 "Center");
7920   gtk_widget_show (window);
7921
7922   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
7923                                 "Static");
7924   gtk_widget_show (window);
7925 }
7926
7927 static GtkWidget*
7928 window_controls (GtkWidget *window)
7929 {
7930   GtkWidget *control_window;
7931   GtkWidget *label;
7932   GtkWidget *vbox;
7933   GtkWidget *button;
7934   GtkWidget *spin;
7935   GtkAdjustment *adjustment;
7936   GtkWidget *entry;
7937   GtkWidget *om;
7938   gint i;
7939   
7940   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7941
7942   gtk_window_set_screen (GTK_WINDOW (control_window),
7943                          gtk_widget_get_screen (window));
7944
7945   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
7946   
7947   g_object_set_data (G_OBJECT (control_window),
7948                      "target",
7949                      window);
7950   
7951   g_signal_connect_object (control_window,
7952                            "destroy",
7953                            G_CALLBACK (gtk_widget_destroy),
7954                            window,
7955                            G_CONNECT_SWAPPED);
7956
7957   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
7958   
7959   gtk_container_add (GTK_CONTAINER (control_window), vbox);
7960   
7961   label = gtk_label_new ("<no configure events>");
7962   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7963   
7964   g_signal_connect (window,
7965                     "configure_event",
7966                     G_CALLBACK (configure_event_callback),
7967                     label);
7968
7969   adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7970   spin = gtk_spin_button_new (adjustment, 0, 0);
7971
7972   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7973
7974   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
7975
7976   adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7977   spin = gtk_spin_button_new (adjustment, 0, 0);
7978
7979   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7980
7981   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
7982
7983   entry = gtk_entry_new ();
7984   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
7985
7986   g_signal_connect (entry, "changed",
7987                     G_CALLBACK (set_geometry_callback),
7988                     control_window);
7989
7990   button = gtk_button_new_with_label ("Show gravity test windows");
7991   g_signal_connect_swapped (button,
7992                             "clicked",
7993                             G_CALLBACK (do_gravity_test),
7994                             control_window);
7995   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7996
7997   button = gtk_button_new_with_label ("Reshow with initial size");
7998   g_signal_connect_object (button,
7999                            "clicked",
8000                            G_CALLBACK (gtk_window_reshow_with_initial_size),
8001                            window,
8002                            G_CONNECT_SWAPPED);
8003   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8004   
8005   button = gtk_button_new_with_label ("Queue resize");
8006   g_signal_connect_object (button,
8007                            "clicked",
8008                            G_CALLBACK (gtk_widget_queue_resize),
8009                            window,
8010                            G_CONNECT_SWAPPED);
8011   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8012   
8013   button = gtk_button_new_with_label ("Resize");
8014   g_signal_connect (button,
8015                     "clicked",
8016                     G_CALLBACK (set_size_callback),
8017                     control_window);
8018   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8019
8020   button = gtk_button_new_with_label ("Set default size");
8021   g_signal_connect (button,
8022                     "clicked",
8023                     G_CALLBACK (set_default_size_callback),
8024                     control_window);
8025   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8026
8027   button = gtk_button_new_with_label ("Unset default size");
8028   g_signal_connect (button,
8029                     "clicked",
8030                     G_CALLBACK (unset_default_size_callback),
8031                     control_window);
8032   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8033   
8034   button = gtk_button_new_with_label ("Set size request");
8035   g_signal_connect (button,
8036                     "clicked",
8037                     G_CALLBACK (set_size_request_callback),
8038                     control_window);
8039   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8040
8041   button = gtk_button_new_with_label ("Unset size request");
8042   g_signal_connect (button,
8043                     "clicked",
8044                     G_CALLBACK (unset_size_request_callback),
8045                     control_window);
8046   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8047   
8048   button = gtk_button_new_with_label ("Move");
8049   g_signal_connect (button,
8050                     "clicked",
8051                     G_CALLBACK (set_location_callback),
8052                     control_window);
8053   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8054
8055   button = gtk_button_new_with_label ("Move to current position");
8056   g_signal_connect (button,
8057                     "clicked",
8058                     G_CALLBACK (move_to_position_callback),
8059                     control_window);
8060   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8061
8062   button = gtk_check_button_new_with_label ("Allow resize");
8063   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8064   g_signal_connect (button,
8065                     "toggled",
8066                     G_CALLBACK (resizable_callback),
8067                     control_window);
8068   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8069   
8070   button = gtk_button_new_with_mnemonic ("_Show");
8071   g_signal_connect_object (button,
8072                            "clicked",
8073                            G_CALLBACK (gtk_widget_show),
8074                            window,
8075                            G_CONNECT_SWAPPED);
8076   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8077
8078   button = gtk_button_new_with_mnemonic ("_Hide");
8079   g_signal_connect_object (button,
8080                            "clicked",
8081                            G_CALLBACK (gtk_widget_hide),
8082                            window,
8083                            G_CONNECT_SWAPPED);
8084   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8085
8086   om = gtk_combo_box_text_new ();
8087   i = 0;
8088   while (i < 10)
8089     {
8090       static gchar *names[] = {
8091         "GDK_GRAVITY_NORTH_WEST",
8092         "GDK_GRAVITY_NORTH",
8093         "GDK_GRAVITY_NORTH_EAST",
8094         "GDK_GRAVITY_WEST",
8095         "GDK_GRAVITY_CENTER",
8096         "GDK_GRAVITY_EAST",
8097         "GDK_GRAVITY_SOUTH_WEST",
8098         "GDK_GRAVITY_SOUTH",
8099         "GDK_GRAVITY_SOUTH_EAST",
8100         "GDK_GRAVITY_STATIC",
8101         NULL
8102       };
8103
8104       g_assert (names[i]);
8105       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8106
8107       ++i;
8108     }
8109   
8110   g_signal_connect (om,
8111                     "changed",
8112                     G_CALLBACK (gravity_selected),
8113                     control_window);
8114
8115   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8116
8117
8118   om = gtk_combo_box_text_new ();
8119   i = 0;
8120   while (i < 5)
8121     {
8122       static gchar *names[] = {
8123         "GTK_WIN_POS_NONE",
8124         "GTK_WIN_POS_CENTER",
8125         "GTK_WIN_POS_MOUSE",
8126         "GTK_WIN_POS_CENTER_ALWAYS",
8127         "GTK_WIN_POS_CENTER_ON_PARENT",
8128         NULL
8129       };
8130
8131       g_assert (names[i]);
8132       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8133
8134       ++i;
8135     }
8136
8137   g_signal_connect (om,
8138                     "changed",
8139                     G_CALLBACK (pos_selected),
8140                     control_window);
8141
8142   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8143   
8144   gtk_widget_show_all (vbox);
8145   
8146   return control_window;
8147 }
8148
8149 void
8150 create_window_sizing (GtkWidget *widget)
8151 {
8152   static GtkWidget *window = NULL;
8153   static GtkWidget *target_window = NULL;
8154
8155   if (!target_window)
8156     {
8157       GtkWidget *label;
8158       
8159       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8160       gtk_window_set_screen (GTK_WINDOW (target_window),
8161                              gtk_widget_get_screen (widget));
8162       label = gtk_label_new (NULL);
8163       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");
8164       gtk_container_add (GTK_CONTAINER (target_window), label);
8165       gtk_widget_show (label);
8166       
8167       g_signal_connect (target_window, "destroy",
8168                         G_CALLBACK (gtk_widget_destroyed),
8169                         &target_window);
8170
8171       window = window_controls (target_window);
8172       
8173       g_signal_connect (window, "destroy",
8174                         G_CALLBACK (gtk_widget_destroyed),
8175                         &window);
8176       
8177       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
8178     }
8179
8180   /* don't show target window by default, we want to allow testing
8181    * of behavior on first show.
8182    */
8183   
8184   if (!gtk_widget_get_visible (window))
8185     gtk_widget_show (window);
8186   else
8187     gtk_widget_destroy (window);
8188 }
8189
8190 /*
8191  * GtkProgressBar
8192  */
8193
8194 typedef struct _ProgressData {
8195   GtkWidget *window;
8196   GtkWidget *pbar;
8197   GtkWidget *block_spin;
8198   GtkWidget *x_align_spin;
8199   GtkWidget *y_align_spin;
8200   GtkWidget *step_spin;
8201   GtkWidget *act_blocks_spin;
8202   GtkWidget *label;
8203   GtkWidget *omenu1;
8204   GtkWidget *elmenu;
8205   GtkWidget *omenu2;
8206   GtkWidget *entry;
8207   int timer;
8208   gboolean activity;
8209 } ProgressData;
8210
8211 gboolean
8212 progress_timeout (gpointer data)
8213 {
8214   ProgressData *pdata = data;
8215   gdouble new_val;
8216   gchar *text;
8217
8218   if (pdata->activity)
8219     {
8220       gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
8221
8222       text = g_strdup_printf ("%s", "???");
8223     }
8224   else
8225     {
8226       new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
8227       if (new_val > 1.00)
8228         new_val = 0.00;
8229       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
8230
8231       text = g_strdup_printf ("%.0f%%", 100 * new_val);
8232     }
8233
8234   gtk_label_set_text (GTK_LABEL (pdata->label), text);
8235   g_free (text);
8236
8237   return TRUE;
8238 }
8239
8240 static void
8241 destroy_progress (GtkWidget     *widget,
8242                   ProgressData **pdata)
8243 {
8244   if ((*pdata)->timer)
8245     {
8246       g_source_remove ((*pdata)->timer);
8247       (*pdata)->timer = 0;
8248     }
8249   (*pdata)->window = NULL;
8250   g_free (*pdata);
8251   *pdata = NULL;
8252 }
8253
8254 static void
8255 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
8256 {
8257   ProgressData *pdata;
8258   gint i;
8259
8260   pdata = (ProgressData *) data;
8261
8262   if (!gtk_widget_get_mapped (widget))
8263     return;
8264
8265   i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8266
8267   if (i == 0 || i == 1)
8268     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_HORIZONTAL);
8269   else
8270     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_VERTICAL);
8271  
8272   if (i == 1 || i == 2)
8273     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
8274   else
8275     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
8276 }
8277
8278 static void
8279 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
8280 {
8281   gboolean active;
8282
8283   active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8284   gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), active);
8285 }
8286
8287 static void
8288 progressbar_toggle_ellipsize (GtkWidget *widget,
8289                               gpointer   data)
8290 {
8291   ProgressData *pdata = data;
8292   if (gtk_widget_is_drawable (widget))
8293     {
8294       gint i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8295       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
8296     }
8297 }
8298
8299 static void
8300 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
8301 {
8302   pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8303 }
8304
8305 static void
8306 toggle_running (GtkWidget *widget, ProgressData *pdata)
8307 {
8308   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
8309     {
8310       if (pdata->timer == 0)
8311         pdata->timer = g_timeout_add (100, (GSourceFunc)progress_timeout, pdata);
8312     }
8313   else
8314     {
8315       if (pdata->timer != 0)
8316         {
8317           g_source_remove (pdata->timer);
8318           pdata->timer = 0;
8319         }
8320     }
8321 }
8322
8323 static void
8324 entry_changed (GtkWidget *widget, ProgressData *pdata)
8325 {
8326   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
8327                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
8328 }
8329
8330 void
8331 create_progress_bar (GtkWidget *widget)
8332 {
8333   GtkWidget *action_area, *content_area;
8334   GtkWidget *button;
8335   GtkWidget *vbox;
8336   GtkWidget *vbox2;
8337   GtkWidget *hbox;
8338   GtkWidget *check;
8339   GtkWidget *frame;
8340   GtkWidget *tab;
8341   GtkWidget *label;
8342   GtkWidget *align;
8343   static ProgressData *pdata = NULL;
8344
8345   static gchar *items1[] =
8346   {
8347     "Left-Right",
8348     "Right-Left",
8349     "Bottom-Top",
8350     "Top-Bottom"
8351   };
8352
8353     static char *ellipsize_items[] = {
8354     "None",     // PANGO_ELLIPSIZE_NONE,
8355     "Start",    // PANGO_ELLIPSIZE_START,
8356     "Middle",   // PANGO_ELLIPSIZE_MIDDLE,
8357     "End",      // PANGO_ELLIPSIZE_END
8358   };
8359   
8360   if (!pdata)
8361     pdata = g_new0 (ProgressData, 1);
8362
8363   if (!pdata->window)
8364     {
8365       pdata->window = gtk_dialog_new ();
8366
8367       gtk_window_set_screen (GTK_WINDOW (pdata->window),
8368                              gtk_widget_get_screen (widget));
8369
8370       gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
8371
8372       g_signal_connect (pdata->window, "destroy",
8373                         G_CALLBACK (destroy_progress),
8374                         &pdata);
8375       pdata->timer = 0;
8376
8377       content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
8378       action_area = gtk_dialog_get_action_area (GTK_DIALOG (pdata->window));
8379
8380       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
8381       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
8382
8383       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8384       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8385       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
8386
8387       frame = gtk_frame_new ("Progress");
8388       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8389
8390       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8391       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8392
8393       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8394       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8395
8396       pdata->pbar = gtk_progress_bar_new ();
8397       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
8398                                       PANGO_ELLIPSIZE_MIDDLE);
8399
8400       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
8401
8402       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8403       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8404
8405       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
8406       gtk_container_add (GTK_CONTAINER (align), hbox);
8407       label = gtk_label_new ("Label updated by user :"); 
8408       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8409       pdata->label = gtk_label_new ("");
8410       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
8411
8412       frame = gtk_frame_new ("Options");
8413       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8414
8415       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8416       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8417
8418       tab = gtk_table_new (7, 2, FALSE);
8419       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
8420
8421       label = gtk_label_new ("Orientation :");
8422       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
8423                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8424                         5, 5);
8425       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8426
8427       pdata->omenu1 = build_option_menu (items1, 4, 0,
8428                                          progressbar_toggle_orientation,
8429                                          pdata);
8430       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8431       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
8432                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8433                         5, 5);
8434       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
8435       
8436       check = gtk_check_button_new_with_label ("Running");
8437       g_signal_connect (check, "toggled",
8438                         G_CALLBACK (toggle_running),
8439                         pdata);
8440       gtk_table_attach (GTK_TABLE (tab), check, 0, 2, 1, 2,
8441                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8442                         5, 5);
8443       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
8444
8445       check = gtk_check_button_new_with_label ("Show text");
8446       g_signal_connect (check, "clicked",
8447                         G_CALLBACK (toggle_show_text),
8448                         pdata);
8449       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 2, 3,
8450                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8451                         5, 5);
8452
8453       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8454       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
8455                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8456                         5, 5);
8457
8458       label = gtk_label_new ("Text: ");
8459       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8460
8461       pdata->entry = gtk_entry_new ();
8462       g_signal_connect (pdata->entry, "changed",
8463                         G_CALLBACK (entry_changed),
8464                         pdata);
8465       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
8466       gtk_widget_set_size_request (pdata->entry, 100, -1);
8467
8468       label = gtk_label_new ("Ellipsize text :");
8469       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 10, 11,
8470                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8471                         5, 5);
8472       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
8473       pdata->elmenu = build_option_menu (ellipsize_items,
8474                                          sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
8475                                          2, // PANGO_ELLIPSIZE_MIDDLE
8476                                          progressbar_toggle_ellipsize,
8477                                          pdata);
8478       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8479       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 10, 11,
8480                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8481                         5, 5);
8482       gtk_box_pack_start (GTK_BOX (hbox), pdata->elmenu, TRUE, TRUE, 0);
8483
8484       check = gtk_check_button_new_with_label ("Activity mode");
8485       g_signal_connect (check, "clicked",
8486                         G_CALLBACK (toggle_activity_mode), pdata);
8487       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 15, 16,
8488                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
8489                         5, 5);
8490
8491       button = gtk_button_new_with_label ("close");
8492       g_signal_connect_swapped (button, "clicked",
8493                                 G_CALLBACK (gtk_widget_destroy),
8494                                 pdata->window);
8495       gtk_widget_set_can_default (button, TRUE);
8496       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8497       gtk_widget_grab_default (button);
8498     }
8499
8500   if (!gtk_widget_get_visible (pdata->window))
8501     gtk_widget_show_all (pdata->window);
8502   else
8503     gtk_widget_destroy (pdata->window);
8504 }
8505
8506 /*
8507  * Properties
8508  */
8509
8510 typedef struct {
8511   int x;
8512   int y;
8513   gboolean found;
8514   gboolean first;
8515   GtkWidget *res_widget;
8516 } FindWidgetData;
8517
8518 static void
8519 find_widget (GtkWidget *widget, FindWidgetData *data)
8520 {
8521   GtkAllocation new_allocation;
8522   gint x_offset = 0;
8523   gint y_offset = 0;
8524
8525   gtk_widget_get_allocation (widget, &new_allocation);
8526
8527   if (data->found || !gtk_widget_get_mapped (widget))
8528     return;
8529
8530   /* Note that in the following code, we only count the
8531    * position as being inside a WINDOW widget if it is inside
8532    * widget->window; points that are outside of widget->window
8533    * but within the allocation are not counted. This is consistent
8534    * with the way we highlight drag targets.
8535    */
8536   if (gtk_widget_get_has_window (widget))
8537     {
8538       new_allocation.x = 0;
8539       new_allocation.y = 0;
8540     }
8541
8542   if (gtk_widget_get_parent (widget) && !data->first)
8543     {
8544       GdkWindow *window = gtk_widget_get_window (widget);
8545       while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
8546         {
8547           gint tx, ty, twidth, theight;
8548           
8549           twidth = gdk_window_get_width (window);
8550           theight = gdk_window_get_height (window);
8551
8552           if (new_allocation.x < 0)
8553             {
8554               new_allocation.width += new_allocation.x;
8555               new_allocation.x = 0;
8556             }
8557           if (new_allocation.y < 0)
8558             {
8559               new_allocation.height += new_allocation.y;
8560               new_allocation.y = 0;
8561             }
8562           if (new_allocation.x + new_allocation.width > twidth)
8563             new_allocation.width = twidth - new_allocation.x;
8564           if (new_allocation.y + new_allocation.height > theight)
8565             new_allocation.height = theight - new_allocation.y;
8566
8567           gdk_window_get_position (window, &tx, &ty);
8568           new_allocation.x += tx;
8569           x_offset += tx;
8570           new_allocation.y += ty;
8571           y_offset += ty;
8572
8573           window = gdk_window_get_parent (window);
8574         }
8575     }
8576
8577   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
8578       (data->x < new_allocation.x + new_allocation.width) && 
8579       (data->y < new_allocation.y + new_allocation.height))
8580     {
8581       /* First, check if the drag is in a valid drop site in
8582        * one of our children 
8583        */
8584       if (GTK_IS_CONTAINER (widget))
8585         {
8586           FindWidgetData new_data = *data;
8587           
8588           new_data.x -= x_offset;
8589           new_data.y -= y_offset;
8590           new_data.found = FALSE;
8591           new_data.first = FALSE;
8592           
8593           gtk_container_forall (GTK_CONTAINER (widget),
8594                                 (GtkCallback)find_widget,
8595                                 &new_data);
8596           
8597           data->found = new_data.found;
8598           if (data->found)
8599             data->res_widget = new_data.res_widget;
8600         }
8601
8602       /* If not, and this widget is registered as a drop site, check to
8603        * emit "drag_motion" to check if we are actually in
8604        * a drop site.
8605        */
8606       if (!data->found)
8607         {
8608           data->found = TRUE;
8609           data->res_widget = widget;
8610         }
8611     }
8612 }
8613
8614 static GtkWidget *
8615 find_widget_at_pointer (GdkDevice *device)
8616 {
8617   GtkWidget *widget = NULL;
8618   GdkWindow *pointer_window;
8619   gint x, y;
8620   FindWidgetData data;
8621  
8622  pointer_window = gdk_device_get_window_at_position (device, NULL, NULL);
8623  
8624  if (pointer_window)
8625    {
8626      gpointer widget_ptr;
8627
8628      gdk_window_get_user_data (pointer_window, &widget_ptr);
8629      widget = widget_ptr;
8630    }
8631
8632  if (widget)
8633    {
8634      gdk_window_get_pointer (gtk_widget_get_window (widget),
8635                              &x, &y, NULL);
8636      
8637      data.x = x;
8638      data.y = y;
8639      data.found = FALSE;
8640      data.first = TRUE;
8641
8642      find_widget (widget, &data);
8643      if (data.found)
8644        return data.res_widget;
8645      return widget;
8646    }
8647  return NULL;
8648 }
8649
8650 struct PropertiesData {
8651   GtkWidget **window;
8652   GdkCursor *cursor;
8653   gboolean in_query;
8654   gulong handler;
8655 };
8656
8657 static void
8658 destroy_properties (GtkWidget             *widget,
8659                     struct PropertiesData *data)
8660 {
8661   if (data->window)
8662     {
8663       *data->window = NULL;
8664       data->window = NULL;
8665     }
8666
8667   if (data->cursor)
8668     {
8669       g_object_unref (data->cursor);
8670       data->cursor = NULL;
8671     }
8672
8673   if (data->handler)
8674     {
8675       g_signal_handler_disconnect (widget, data->handler);
8676       data->handler = 0;
8677     }
8678
8679   g_free (data);
8680 }
8681
8682 static gint
8683 property_query_event (GtkWidget             *widget,
8684                       GdkEvent              *event,
8685                       struct PropertiesData *data)
8686 {
8687   GtkWidget *res_widget = NULL;
8688
8689   if (!data->in_query)
8690     return FALSE;
8691
8692   if (event->type == GDK_BUTTON_RELEASE)
8693     {
8694       gtk_grab_remove (widget);
8695       gdk_device_ungrab (gdk_event_get_device (event), GDK_CURRENT_TIME);
8696
8697       res_widget = find_widget_at_pointer (gdk_event_get_device (event));
8698       if (res_widget)
8699         {
8700           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
8701                              gtk_widget_get_screen (widget));
8702           create_prop_editor (G_OBJECT (res_widget), 0);
8703         }
8704
8705       data->in_query = FALSE;
8706     }
8707   return FALSE;
8708 }
8709
8710
8711 static void
8712 query_properties (GtkButton *button,
8713                   struct PropertiesData *data)
8714 {
8715   GtkWidget *widget = GTK_WIDGET (button);
8716   GdkDisplay *display;
8717   GdkDeviceManager *device_manager;
8718   GdkDevice *device;
8719
8720   g_signal_connect (button, "event",
8721                     G_CALLBACK (property_query_event), data);
8722
8723   display = gtk_widget_get_display (widget);
8724
8725   if (!data->cursor)
8726     data->cursor = gdk_cursor_new_for_display (display, GDK_TARGET);
8727
8728   device_manager = gdk_display_get_device_manager (display);
8729   device = gdk_device_manager_get_client_pointer (device_manager);
8730   gdk_device_grab (device,
8731                    gtk_widget_get_window (widget),
8732                    GDK_OWNERSHIP_NONE,
8733                    TRUE,
8734                    GDK_BUTTON_RELEASE_MASK,
8735                    data->cursor,
8736                    GDK_CURRENT_TIME);
8737   gtk_grab_add (widget);
8738
8739   data->in_query = TRUE;
8740 }
8741
8742 static void
8743 create_properties (GtkWidget *widget)
8744 {
8745   static GtkWidget *window = NULL;
8746   GtkWidget *button;
8747   GtkWidget *vbox;
8748   GtkWidget *label;
8749   struct PropertiesData *data;
8750
8751   data = g_new (struct PropertiesData, 1);
8752   data->window = &window;
8753   data->in_query = FALSE;
8754   data->cursor = NULL;
8755   data->handler = 0;
8756
8757   if (!window)
8758     {
8759       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8760
8761       gtk_window_set_screen (GTK_WINDOW (window),
8762                              gtk_widget_get_screen (widget));      
8763
8764       data->handler = g_signal_connect (window, "destroy",
8765                                         G_CALLBACK (destroy_properties),
8766                                         data);
8767
8768       gtk_window_set_title (GTK_WINDOW (window), "test properties");
8769       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8770
8771       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
8772       gtk_container_add (GTK_CONTAINER (window), vbox);
8773             
8774       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
8775       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
8776       
8777       button = gtk_button_new_with_label ("Query properties");
8778       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8779       g_signal_connect (button, "clicked",
8780                         G_CALLBACK (query_properties),
8781                         data);
8782     }
8783
8784   if (!gtk_widget_get_visible (window))
8785     gtk_widget_show_all (window);
8786   else
8787     gtk_widget_destroy (window);
8788   
8789 }
8790
8791 struct SnapshotData {
8792   GtkWidget *toplevel_button;
8793   GtkWidget **window;
8794   GdkCursor *cursor;
8795   gboolean in_query;
8796   gboolean is_toplevel;
8797   gint handler;
8798 };
8799
8800 static void
8801 destroy_snapshot_data (GtkWidget             *widget,
8802                        struct SnapshotData *data)
8803 {
8804   if (*data->window)
8805     *data->window = NULL;
8806   
8807   if (data->cursor)
8808     {
8809       g_object_unref (data->cursor);
8810       data->cursor = NULL;
8811     }
8812
8813   if (data->handler)
8814     {
8815       g_signal_handler_disconnect (widget, data->handler);
8816       data->handler = 0;
8817     }
8818
8819   g_free (data);
8820 }
8821
8822 static gint
8823 snapshot_widget_event (GtkWidget               *widget,
8824                        GdkEvent        *event,
8825                        struct SnapshotData *data)
8826 {
8827   GtkWidget *res_widget = NULL;
8828
8829   if (!data->in_query)
8830     return FALSE;
8831   
8832   if (event->type == GDK_BUTTON_RELEASE)
8833     {
8834       gtk_grab_remove (widget);
8835       gdk_device_ungrab (gdk_event_get_device (event),
8836                          GDK_CURRENT_TIME);
8837       
8838       res_widget = find_widget_at_pointer (gdk_event_get_device (event));
8839       if (data->is_toplevel && res_widget)
8840         res_widget = gtk_widget_get_toplevel (res_widget);
8841       if (res_widget)
8842         {
8843           cairo_surface_t *surface;
8844           GtkWidget *window, *image;
8845           GdkPixbuf *pixbuf;
8846           int width, height;
8847           cairo_t *cr;
8848
8849           width = gtk_widget_get_allocated_width (res_widget);
8850           height = gtk_widget_get_allocated_height (res_widget);
8851
8852           surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
8853
8854           cr = cairo_create (surface);
8855           gtk_widget_draw (res_widget, cr);
8856           cairo_destroy (cr);
8857
8858           pixbuf = gdk_pixbuf_get_from_surface (surface,
8859                                                 0, 0,
8860                                                 width, height);
8861           cairo_surface_destroy (surface);
8862
8863           window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8864           image = gtk_image_new_from_pixbuf (pixbuf);
8865           g_object_unref (pixbuf);
8866
8867           gtk_container_add (GTK_CONTAINER (window), image);
8868           gtk_widget_show_all (window);
8869         }
8870
8871       data->in_query = FALSE;
8872     }
8873   return FALSE;
8874 }
8875
8876
8877 static void
8878 snapshot_widget (GtkButton *button,
8879                  struct SnapshotData *data)
8880 {
8881   GtkWidget *widget = GTK_WIDGET (button);
8882   GdkDevice *device;
8883
8884   device = gtk_get_current_event_device ();
8885   if (device == NULL)
8886     return;
8887
8888   if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
8889     device = gdk_device_get_associated_device (device);
8890
8891   data->is_toplevel = widget == data->toplevel_button;
8892
8893   if (!data->cursor)
8894     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8895                                                GDK_TARGET);
8896
8897   gdk_device_grab (device,
8898                    gtk_widget_get_window (widget),
8899                    GDK_OWNERSHIP_APPLICATION,
8900                    TRUE,
8901                    GDK_BUTTON_RELEASE_MASK,
8902                    data->cursor,
8903                    GDK_CURRENT_TIME);
8904
8905   g_signal_connect (button, "event",
8906                     G_CALLBACK (snapshot_widget_event), data);
8907
8908   gtk_grab_add (widget);
8909
8910   data->in_query = TRUE;
8911 }
8912
8913 static void
8914 create_snapshot (GtkWidget *widget)
8915 {
8916   static GtkWidget *window = NULL;
8917   GtkWidget *button;
8918   GtkWidget *vbox;
8919   struct SnapshotData *data;
8920
8921   data = g_new (struct SnapshotData, 1);
8922   data->window = &window;
8923   data->in_query = FALSE;
8924   data->cursor = NULL;
8925   data->handler = 0;
8926
8927   if (!window)
8928     {
8929       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8930
8931       gtk_window_set_screen (GTK_WINDOW (window),
8932                              gtk_widget_get_screen (widget));      
8933
8934       data->handler = g_signal_connect (window, "destroy",
8935                                         G_CALLBACK (destroy_snapshot_data),
8936                                         data);
8937
8938       gtk_window_set_title (GTK_WINDOW (window), "test snapshot");
8939       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8940
8941       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
8942       gtk_container_add (GTK_CONTAINER (window), vbox);
8943             
8944       button = gtk_button_new_with_label ("Snapshot widget");
8945       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8946       g_signal_connect (button, "clicked",
8947                         G_CALLBACK (snapshot_widget),
8948                         data);
8949       
8950       button = gtk_button_new_with_label ("Snapshot toplevel");
8951       data->toplevel_button = button;
8952       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8953       g_signal_connect (button, "clicked",
8954                         G_CALLBACK (snapshot_widget),
8955                         data);
8956     }
8957
8958   if (!gtk_widget_get_visible (window))
8959     gtk_widget_show_all (window);
8960   else
8961     gtk_widget_destroy (window);
8962   
8963 }
8964
8965 /*
8966  * Selection Test
8967  */
8968
8969 void
8970 selection_test_received (GtkWidget        *tree_view,
8971                          GtkSelectionData *selection_data)
8972 {
8973   GtkTreeModel *model;
8974   GtkListStore *store;
8975   GdkAtom *atoms;
8976   int i, l;
8977
8978   if (gtk_selection_data_get_length (selection_data) < 0)
8979     {
8980       g_print ("Selection retrieval failed\n");
8981       return;
8982     }
8983   if (gtk_selection_data_get_data_type (selection_data) != GDK_SELECTION_TYPE_ATOM)
8984     {
8985       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
8986       return;
8987     }
8988
8989   /* Clear out any current list items */
8990
8991   model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
8992   store = GTK_LIST_STORE (model);
8993   gtk_list_store_clear (store);
8994
8995   /* Add new items to list */
8996
8997   gtk_selection_data_get_targets (selection_data,
8998                                   &atoms, &l);
8999
9000   for (i = 0; i < l; i++)
9001     {
9002       char *name;
9003       GtkTreeIter iter;
9004
9005       name = gdk_atom_name (atoms[i]);
9006       if (name != NULL)
9007         {
9008           gtk_list_store_insert_with_values (store, &iter, i, 0, name, -1);
9009           g_free (name);
9010         }
9011       else
9012        gtk_list_store_insert_with_values (store, &iter, i, 0,  "(bad atom)", -1);
9013     }
9014
9015   return;
9016 }
9017
9018 void
9019 selection_test_get_targets (GtkWidget *widget, GtkWidget *tree_view)
9020 {
9021   static GdkAtom targets_atom = GDK_NONE;
9022
9023   if (targets_atom == GDK_NONE)
9024     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
9025
9026   gtk_selection_convert (tree_view, GDK_SELECTION_PRIMARY, targets_atom,
9027                          GDK_CURRENT_TIME);
9028 }
9029
9030 void
9031 create_selection_test (GtkWidget *widget)
9032 {
9033   static GtkWidget *window = NULL;
9034   GtkWidget *action_area, *content_area;
9035   GtkWidget *button;
9036   GtkWidget *vbox;
9037   GtkWidget *scrolled_win;
9038   GtkListStore* store;
9039   GtkWidget *tree_view;
9040   GtkTreeViewColumn *column;
9041   GtkCellRenderer *renderer;
9042   GtkWidget *label;
9043
9044   if (!window)
9045     {
9046       window = gtk_dialog_new ();
9047       
9048       gtk_window_set_screen (GTK_WINDOW (window),
9049                              gtk_widget_get_screen (widget));
9050
9051       g_signal_connect (window, "destroy",
9052                         G_CALLBACK (gtk_widget_destroyed),
9053                         &window);
9054
9055       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9056       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9057
9058       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
9059       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9060
9061       /* Create the list */
9062
9063       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
9064       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9065       gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
9066
9067       label = gtk_label_new ("Gets available targets for current selection");
9068       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9069
9070       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
9071       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
9072                                       GTK_POLICY_AUTOMATIC, 
9073                                       GTK_POLICY_AUTOMATIC);
9074       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
9075       gtk_widget_set_size_request (scrolled_win, 100, 200);
9076
9077       store = gtk_list_store_new (1, G_TYPE_STRING);
9078       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
9079       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), tree_view);
9080
9081       renderer = gtk_cell_renderer_text_new ();
9082       column = gtk_tree_view_column_new_with_attributes ("Target", renderer,
9083                                                          "text", 0, NULL);
9084       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
9085
9086       g_signal_connect (tree_view, "selection_received",
9087                         G_CALLBACK (selection_test_received), NULL);
9088
9089       /* .. And create some buttons */
9090       button = gtk_button_new_with_label ("Get Targets");
9091       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9092
9093       g_signal_connect (button, "clicked",
9094                         G_CALLBACK (selection_test_get_targets), tree_view);
9095
9096       button = gtk_button_new_with_label ("Quit");
9097       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9098
9099       g_signal_connect_swapped (button, "clicked",
9100                                 G_CALLBACK (gtk_widget_destroy),
9101                                 window);
9102     }
9103
9104   if (!gtk_widget_get_visible (window))
9105     gtk_widget_show_all (window);
9106   else
9107     gtk_widget_destroy (window);
9108 }
9109
9110 /*
9111  * Test scrolling
9112  */
9113
9114 static int scroll_test_pos = 0.0;
9115
9116 static gint
9117 scroll_test_draw (GtkWidget     *widget,
9118                   cairo_t       *cr,
9119                   GtkAdjustment *adjustment)
9120 {
9121   gint i,j;
9122   gint imin, imax, jmin, jmax;
9123   GdkRectangle clip;
9124   
9125   gdk_cairo_get_clip_rectangle (cr, &clip);
9126
9127   imin = (clip.x) / 10;
9128   imax = (clip.x + clip.width + 9) / 10;
9129
9130   jmin = ((int)gtk_adjustment_get_value (adjustment) + clip.y) / 10;
9131   jmax = ((int)gtk_adjustment_get_value (adjustment) + clip.y + clip.height + 9) / 10;
9132
9133   for (i=imin; i<imax; i++)
9134     for (j=jmin; j<jmax; j++)
9135       if ((i+j) % 2)
9136         cairo_rectangle (cr, 10*i, 10*j - (int)gtk_adjustment_get_value (adjustment), 1+i%10, 1+j%10);
9137
9138   cairo_fill (cr);
9139
9140   return TRUE;
9141 }
9142
9143 static gint
9144 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
9145                     GtkAdjustment *adjustment)
9146 {
9147   gdouble new_value = gtk_adjustment_get_value (adjustment) + ((event->direction == GDK_SCROLL_UP) ?
9148                                     -gtk_adjustment_get_page_increment (adjustment) / 2:
9149                                     gtk_adjustment_get_page_increment (adjustment) / 2);
9150   new_value = CLAMP (new_value, gtk_adjustment_get_lower (adjustment), gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment));
9151   gtk_adjustment_set_value (adjustment, new_value);  
9152   
9153   return TRUE;
9154 }
9155
9156 static void
9157 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
9158                        GtkAdjustment *adjustment)
9159 {
9160   GtkAllocation allocation;
9161
9162   gtk_widget_get_allocation (widget, &allocation);
9163   gtk_adjustment_configure (adjustment,
9164                             gtk_adjustment_get_value (adjustment),
9165                             gtk_adjustment_get_lower (adjustment),
9166                             gtk_adjustment_get_upper (adjustment),
9167                             0.1 * allocation.height,
9168                             0.9 * allocation.height,
9169                             allocation.height);
9170 }
9171
9172 static void
9173 scroll_test_adjustment_changed (GtkAdjustment *adjustment, GtkWidget *widget)
9174 {
9175   GdkWindow *window;
9176   gint dy;
9177
9178   dy = scroll_test_pos - (int)gtk_adjustment_get_value (adjustment);
9179   scroll_test_pos = gtk_adjustment_get_value (adjustment);
9180
9181   if (!gtk_widget_is_drawable (widget))
9182     return;
9183
9184   window = gtk_widget_get_window (widget);
9185   gdk_window_scroll (window, 0, dy);
9186   gdk_window_process_updates (window, FALSE);
9187 }
9188
9189
9190 void
9191 create_scroll_test (GtkWidget *widget)
9192 {
9193   static GtkWidget *window = NULL;
9194   GtkWidget *action_area, *content_area;
9195   GtkWidget *hbox;
9196   GtkWidget *drawing_area;
9197   GtkWidget *scrollbar;
9198   GtkWidget *button;
9199   GtkAdjustment *adjustment;
9200   GdkGeometry geometry;
9201   GdkWindowHints geometry_mask;
9202
9203   if (!window)
9204     {
9205       window = gtk_dialog_new ();
9206
9207       gtk_window_set_screen (GTK_WINDOW (window),
9208                              gtk_widget_get_screen (widget));
9209
9210       g_signal_connect (window, "destroy",
9211                         G_CALLBACK (gtk_widget_destroyed),
9212                         &window);
9213
9214       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9215       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9216
9217       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
9218       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9219
9220       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
9221       gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
9222       gtk_widget_show (hbox);
9223
9224       drawing_area = gtk_drawing_area_new ();
9225       gtk_widget_set_size_request (drawing_area, 200, 200);
9226       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
9227       gtk_widget_show (drawing_area);
9228
9229       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
9230
9231       adjustment = gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0);
9232       scroll_test_pos = 0.0;
9233
9234       scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, adjustment);
9235       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
9236       gtk_widget_show (scrollbar);
9237
9238       g_signal_connect (drawing_area, "draw",
9239                         G_CALLBACK (scroll_test_draw), adjustment);
9240       g_signal_connect (drawing_area, "configure_event",
9241                         G_CALLBACK (scroll_test_configure), adjustment);
9242       g_signal_connect (drawing_area, "scroll_event",
9243                         G_CALLBACK (scroll_test_scroll), adjustment);
9244       
9245       g_signal_connect (adjustment, "value_changed",
9246                         G_CALLBACK (scroll_test_adjustment_changed),
9247                         drawing_area);
9248       
9249       /* .. And create some buttons */
9250
9251       button = gtk_button_new_with_label ("Quit");
9252       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9253
9254       g_signal_connect_swapped (button, "clicked",
9255                                 G_CALLBACK (gtk_widget_destroy),
9256                                 window);
9257       gtk_widget_show (button);
9258
9259       /* Set up gridded geometry */
9260
9261       geometry_mask = GDK_HINT_MIN_SIZE | 
9262                        GDK_HINT_BASE_SIZE | 
9263                        GDK_HINT_RESIZE_INC;
9264
9265       geometry.min_width = 20;
9266       geometry.min_height = 20;
9267       geometry.base_width = 0;
9268       geometry.base_height = 0;
9269       geometry.width_inc = 10;
9270       geometry.height_inc = 10;
9271       
9272       gtk_window_set_geometry_hints (GTK_WINDOW (window),
9273                                drawing_area, &geometry, geometry_mask);
9274     }
9275
9276   if (!gtk_widget_get_visible (window))
9277     gtk_widget_show (window);
9278   else
9279     gtk_widget_destroy (window);
9280 }
9281
9282 /*
9283  * Timeout Test
9284  */
9285
9286 static int timer = 0;
9287
9288 gint
9289 timeout_test (GtkWidget *label)
9290 {
9291   static int count = 0;
9292   static char buffer[32];
9293
9294   sprintf (buffer, "count: %d", ++count);
9295   gtk_label_set_text (GTK_LABEL (label), buffer);
9296
9297   return TRUE;
9298 }
9299
9300 void
9301 start_timeout_test (GtkWidget *widget,
9302                     GtkWidget *label)
9303 {
9304   if (!timer)
9305     {
9306       timer = g_timeout_add (100, (GSourceFunc)timeout_test, label);
9307     }
9308 }
9309
9310 void
9311 stop_timeout_test (GtkWidget *widget,
9312                    gpointer   data)
9313 {
9314   if (timer)
9315     {
9316       g_source_remove (timer);
9317       timer = 0;
9318     }
9319 }
9320
9321 void
9322 destroy_timeout_test (GtkWidget  *widget,
9323                       GtkWidget **window)
9324 {
9325   stop_timeout_test (NULL, NULL);
9326
9327   *window = NULL;
9328 }
9329
9330 void
9331 create_timeout_test (GtkWidget *widget)
9332 {
9333   static GtkWidget *window = NULL;
9334   GtkWidget *action_area, *content_area;
9335   GtkWidget *button;
9336   GtkWidget *label;
9337
9338   if (!window)
9339     {
9340       window = gtk_dialog_new ();
9341
9342       gtk_window_set_screen (GTK_WINDOW (window),
9343                              gtk_widget_get_screen (widget));
9344
9345       g_signal_connect (window, "destroy",
9346                         G_CALLBACK (destroy_timeout_test),
9347                         &window);
9348
9349       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9350       action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9351
9352       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
9353       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9354
9355       label = gtk_label_new ("count: 0");
9356       g_object_set (label, "margin", 10, NULL);
9357       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9358       gtk_widget_show (label);
9359
9360       button = gtk_button_new_with_label ("close");
9361       g_signal_connect_swapped (button, "clicked",
9362                                 G_CALLBACK (gtk_widget_destroy),
9363                                 window);
9364       gtk_widget_set_can_default (button, TRUE);
9365       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9366       gtk_widget_grab_default (button);
9367       gtk_widget_show (button);
9368
9369       button = gtk_button_new_with_label ("start");
9370       g_signal_connect (button, "clicked",
9371                         G_CALLBACK(start_timeout_test),
9372                         label);
9373       gtk_widget_set_can_default (button, TRUE);
9374       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9375       gtk_widget_show (button);
9376
9377       button = gtk_button_new_with_label ("stop");
9378       g_signal_connect (button, "clicked",
9379                         G_CALLBACK (stop_timeout_test),
9380                         NULL);
9381       gtk_widget_set_can_default (button, TRUE);
9382       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9383       gtk_widget_show (button);
9384     }
9385
9386   if (!gtk_widget_get_visible (window))
9387     gtk_widget_show (window);
9388   else
9389     gtk_widget_destroy (window);
9390 }
9391
9392 /*
9393  * Idle Test
9394  */
9395
9396 static int idle_id = 0;
9397
9398 static gint
9399 idle_test (GtkWidget *label)
9400 {
9401   static int count = 0;
9402   static char buffer[32];
9403
9404   sprintf (buffer, "count: %d", ++count);
9405   gtk_label_set_text (GTK_LABEL (label), buffer);
9406
9407   return TRUE;
9408 }
9409
9410 static void
9411 start_idle_test (GtkWidget *widget,
9412                  GtkWidget *label)
9413 {
9414   if (!idle_id)
9415     {
9416       idle_id = g_idle_add ((GSourceFunc) idle_test, label);
9417     }
9418 }
9419
9420 static void
9421 stop_idle_test (GtkWidget *widget,
9422                 gpointer   data)
9423 {
9424   if (idle_id)
9425     {
9426       g_source_remove (idle_id);
9427       idle_id = 0;
9428     }
9429 }
9430
9431 static void
9432 destroy_idle_test (GtkWidget  *widget,
9433                    GtkWidget **window)
9434 {
9435   stop_idle_test (NULL, NULL);
9436
9437   *window = NULL;
9438 }
9439
9440 static void
9441 toggle_idle_container (GObject *button,
9442                        GtkContainer *container)
9443 {
9444   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
9445 }
9446
9447 static void
9448 create_idle_test (GtkWidget *widget)
9449 {
9450   static GtkWidget *window = NULL;
9451   GtkWidget *button;
9452   GtkWidget *label;
9453   GtkWidget *container;
9454
9455   if (!window)
9456     {
9457       GtkWidget *action_area, *content_area;
9458       GtkWidget *button2;
9459       GtkWidget *frame;
9460       GtkWidget *box;
9461
9462       window = gtk_dialog_new ();
9463
9464       gtk_window_set_screen (GTK_WINDOW (window),
9465                              gtk_widget_get_screen (widget));
9466
9467       g_signal_connect (window, "destroy",
9468                         G_CALLBACK (destroy_idle_test),
9469                         &window);
9470
9471       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9472       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9473
9474       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
9475       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9476
9477       label = gtk_label_new ("count: 0");
9478       g_object_set (label, "margin", 10, NULL);
9479       gtk_widget_show (label);
9480       
9481       container =
9482         g_object_new (GTK_TYPE_BOX,
9483                         "visible", TRUE,
9484                         /* "GtkContainer::child", g_object_new (GTK_TYPE_HBOX,
9485                          * "GtkWidget::visible", TRUE,
9486                          */
9487                          "child", label,
9488                         /* NULL), */
9489                         NULL);
9490       gtk_box_pack_start (GTK_BOX (content_area), container, TRUE, TRUE, 0);
9491
9492       frame =
9493         g_object_new (GTK_TYPE_FRAME,
9494                         "border_width", 5,
9495                         "label", "Label Container",
9496                         "visible", TRUE,
9497                         "parent", content_area,
9498                         NULL);
9499       box =
9500         g_object_new (GTK_TYPE_BOX,
9501                         "visible", TRUE,
9502                         "parent", frame,
9503                         "orientation", GTK_ORIENTATION_VERTICAL,
9504                         NULL);
9505       button =
9506         g_object_connect (g_object_new (GTK_TYPE_RADIO_BUTTON,
9507                                           "label", "Resize-Parent",
9508                                           "user_data", (void*)GTK_RESIZE_PARENT,
9509                                           "visible", TRUE,
9510                                           "parent", box,
9511                                           NULL),
9512                           "signal::clicked", toggle_idle_container, container,
9513                           NULL);
9514       button = g_object_new (GTK_TYPE_RADIO_BUTTON,
9515                                "label", "Resize-Queue",
9516                                "user_data", (void*)GTK_RESIZE_QUEUE,
9517                                "group", button,
9518                                "visible", TRUE,
9519                                "parent", box,
9520                                NULL);
9521       g_object_connect (button,
9522                         "signal::clicked", toggle_idle_container, container,
9523                         NULL);
9524       button2 = g_object_new (GTK_TYPE_RADIO_BUTTON,
9525                                 "label", "Resize-Immediate",
9526                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
9527                                 NULL);
9528       g_object_connect (button2,
9529                         "signal::clicked", toggle_idle_container, container,
9530                         NULL);
9531       g_object_set (button2,
9532                     "group", button,
9533                     "visible", TRUE,
9534                     "parent", box,
9535                     NULL);
9536
9537       button = gtk_button_new_with_label ("close");
9538       g_signal_connect_swapped (button, "clicked",
9539                                 G_CALLBACK (gtk_widget_destroy),
9540                                 window);
9541       gtk_widget_set_can_default (button, TRUE);
9542       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9543       gtk_widget_grab_default (button);
9544       gtk_widget_show (button);
9545
9546       button = gtk_button_new_with_label ("start");
9547       g_signal_connect (button, "clicked",
9548                         G_CALLBACK (start_idle_test),
9549                         label);
9550       gtk_widget_set_can_default (button, TRUE);
9551       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9552       gtk_widget_show (button);
9553
9554       button = gtk_button_new_with_label ("stop");
9555       g_signal_connect (button, "clicked",
9556                         G_CALLBACK (stop_idle_test),
9557                         NULL);
9558       gtk_widget_set_can_default (button, TRUE);
9559       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9560       gtk_widget_show (button);
9561     }
9562
9563   if (!gtk_widget_get_visible (window))
9564     gtk_widget_show (window);
9565   else
9566     gtk_widget_destroy (window);
9567 }
9568
9569 /*
9570  * rc file test
9571  */
9572
9573 void
9574 create_rc_file (GtkWidget *widget)
9575 {
9576   static GtkWidget *window = NULL;
9577   GtkWidget *action_area, *content_area;
9578   GtkWidget *button;
9579   GtkWidget *frame;
9580   GtkWidget *vbox;
9581   GtkWidget *label;
9582
9583   if (!window)
9584     {
9585       window = gtk_dialog_new ();
9586
9587       gtk_window_set_screen (GTK_WINDOW (window),
9588                              gtk_widget_get_screen (widget));
9589
9590       g_signal_connect (window, "destroy",
9591                         G_CALLBACK (gtk_widget_destroyed),
9592                         &window);
9593
9594       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9595       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9596
9597       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
9598       gtk_box_pack_start (GTK_BOX (content_area), frame, FALSE, FALSE, 0);
9599
9600       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9601       gtk_container_add (GTK_CONTAINER (frame), vbox);
9602       
9603       label = gtk_label_new ("This label should be red");
9604       gtk_widget_set_name (label, "testgtk-red-label");
9605       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9606
9607       label = gtk_label_new ("This label should be green");
9608       gtk_widget_set_name (label, "testgtk-green-label");
9609       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9610
9611       label = gtk_label_new ("This label should be blue");
9612       gtk_widget_set_name (label, "testgtk-blue-label");
9613       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9614
9615       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
9616       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9617
9618       button = gtk_button_new_with_label ("Reload");
9619       g_signal_connect_swapped (button, "clicked",
9620                                 G_CALLBACK (gtk_style_context_reset_widgets),
9621                                 gtk_widget_get_screen (button));
9622       gtk_widget_set_can_default (button, TRUE);
9623       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9624       gtk_widget_grab_default (button);
9625
9626       button = gtk_button_new_with_label ("Close");
9627       g_signal_connect_swapped (button, "clicked",
9628                                 G_CALLBACK (gtk_widget_destroy),
9629                                 window);
9630       gtk_widget_set_can_default (button, TRUE);
9631       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9632     }
9633
9634   if (!gtk_widget_get_visible (window))
9635     gtk_widget_show_all (window);
9636   else
9637     gtk_widget_destroy (window);
9638 }
9639
9640 /*
9641  * Test of recursive mainloop
9642  */
9643
9644 void
9645 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
9646 {
9647   *window = NULL;
9648   gtk_main_quit ();
9649 }
9650
9651 void
9652 create_mainloop (GtkWidget *widget)
9653 {
9654   static GtkWidget *window = NULL;
9655   GtkWidget *action_area, *content_area;
9656   GtkWidget *label;
9657   GtkWidget *button;
9658
9659   if (!window)
9660     {
9661       window = gtk_dialog_new ();
9662
9663       gtk_window_set_screen (GTK_WINDOW (window),
9664                              gtk_widget_get_screen (widget));
9665
9666       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
9667
9668       g_signal_connect (window, "destroy",
9669                         G_CALLBACK (mainloop_destroyed),
9670                         &window);
9671
9672       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9673       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9674
9675       label = gtk_label_new ("In recursive main loop...");
9676       g_object_set (label, "margin", 20, NULL);
9677
9678       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9679       gtk_widget_show (label);
9680
9681       button = gtk_button_new_with_label ("Leave");
9682       gtk_box_pack_start (GTK_BOX (action_area), button, FALSE, TRUE, 0);
9683
9684       g_signal_connect_swapped (button, "clicked",
9685                                 G_CALLBACK (gtk_widget_destroy),
9686                                 window);
9687
9688       gtk_widget_set_can_default (button, TRUE);
9689       gtk_widget_grab_default (button);
9690
9691       gtk_widget_show (button);
9692     }
9693
9694   if (!gtk_widget_get_visible (window))
9695     {
9696       gtk_widget_show (window);
9697
9698       g_print ("create_mainloop: start\n");
9699       gtk_main ();
9700       g_print ("create_mainloop: done\n");
9701     }
9702   else
9703     gtk_widget_destroy (window);
9704 }
9705
9706 static gboolean
9707 layout_draw_handler (GtkWidget *widget, cairo_t *cr)
9708 {
9709   GtkLayout *layout;
9710   GdkWindow *bin_window;
9711   GdkRectangle clip;
9712   gint i,j,x,y;
9713   gint imin, imax, jmin, jmax;
9714
9715   layout = GTK_LAYOUT (widget);
9716   bin_window = gtk_layout_get_bin_window (layout);
9717
9718   if (!gtk_cairo_should_draw_window (cr, bin_window))
9719     return FALSE;
9720   
9721   gdk_window_get_position (bin_window, &x, &y);
9722   cairo_translate (cr, x, y);
9723
9724   gdk_cairo_get_clip_rectangle (cr, &clip);
9725
9726   imin = (clip.x) / 10;
9727   imax = (clip.x + clip.width + 9) / 10;
9728
9729   jmin = (clip.y) / 10;
9730   jmax = (clip.y + clip.height + 9) / 10;
9731
9732   for (i=imin; i<imax; i++)
9733     for (j=jmin; j<jmax; j++)
9734       if ((i+j) % 2)
9735         cairo_rectangle (cr,
9736                          10*i, 10*j, 
9737                          1+i%10, 1+j%10);
9738   
9739   cairo_fill (cr);
9740
9741   return FALSE;
9742 }
9743
9744 void create_layout (GtkWidget *widget)
9745 {
9746   GtkAdjustment *hadjustment, *vadjustment;
9747   GtkLayout *layout;
9748   static GtkWidget *window = NULL;
9749   GtkWidget *layout_widget;
9750   GtkWidget *scrolledwindow;
9751   GtkWidget *button;
9752
9753   if (!window)
9754     {
9755       gchar buf[16];
9756
9757       gint i, j;
9758       
9759       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9760       gtk_window_set_screen (GTK_WINDOW (window),
9761                              gtk_widget_get_screen (widget));
9762
9763       g_signal_connect (window, "destroy",
9764                         G_CALLBACK (gtk_widget_destroyed),
9765                         &window);
9766
9767       gtk_window_set_title (GTK_WINDOW (window), "Layout");
9768       gtk_widget_set_size_request (window, 200, 200);
9769
9770       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
9771       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
9772                                            GTK_SHADOW_IN);
9773       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
9774                                          GTK_CORNER_TOP_RIGHT);
9775
9776       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
9777
9778       layout_widget = gtk_layout_new (NULL, NULL);
9779       layout = GTK_LAYOUT (layout_widget);
9780       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);
9781
9782       /* We set step sizes here since GtkLayout does not set
9783        * them itself.
9784        */
9785       hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout));
9786       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (layout));
9787       gtk_adjustment_set_step_increment (hadjustment, 10.0);
9788       gtk_adjustment_set_step_increment (vadjustment, 10.0);
9789       gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (layout), hadjustment);
9790       gtk_scrollable_set_vadjustment (GTK_SCROLLABLE (layout), vadjustment);
9791
9792       gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
9793       g_signal_connect (layout, "draw",
9794                         G_CALLBACK (layout_draw_handler), NULL);
9795
9796       gtk_layout_set_size (layout, 1600, 128000);
9797
9798       for (i=0 ; i < 16 ; i++)
9799         for (j=0 ; j < 16 ; j++)
9800           {
9801             sprintf(buf, "Button %d, %d", i, j);
9802             if ((i + j) % 2)
9803               button = gtk_button_new_with_label (buf);
9804             else
9805               button = gtk_label_new (buf);
9806
9807             gtk_layout_put (layout, button, j*100, i*100);
9808           }
9809
9810       for (i=16; i < 1280; i++)
9811         {
9812           sprintf(buf, "Button %d, %d", i, 0);
9813           if (i % 2)
9814             button = gtk_button_new_with_label (buf);
9815           else
9816             button = gtk_label_new (buf);
9817
9818           gtk_layout_put (layout, button, 0, i*100);
9819         }
9820     }
9821
9822   if (!gtk_widget_get_visible (window))
9823     gtk_widget_show_all (window);
9824   else
9825     gtk_widget_destroy (window);
9826 }
9827
9828 #if 0
9829 /* FIXME: need to completely redo this for GtkStyleContext */
9830 void
9831 create_styles (GtkWidget *widget)
9832 {
9833   static GtkWidget *window = NULL;
9834   GtkWidget *content_area, *action_area;
9835   GtkWidget *label;
9836   GtkWidget *button;
9837   GtkWidget *entry;
9838   GtkWidget *vbox;
9839   static GdkRGBA red =    { 1,0,0,1 };
9840   static GdkRGBA green =  { 0,1,0,1 };
9841   static GdkRGBA blue =   { 0,0,1,1 };
9842   static GdkRGBA yellow = { 1,1,0,1 };
9843   static GdkRGBA cyan =   { 0,1,1,1 };
9844   PangoFontDescription *font_desc;
9845
9846   GtkRcStyle *rc_style;
9847
9848   if (!window)
9849     {
9850       window = gtk_dialog_new ();
9851       gtk_window_set_screen (GTK_WINDOW (window),
9852                              gtk_widget_get_screen (widget));
9853      
9854       g_signal_connect (window, "destroy",
9855                         G_CALLBACK (gtk_widget_destroyed),
9856                         &window);
9857
9858       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9859       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9860
9861       button = gtk_button_new_with_label ("Close");
9862       g_signal_connect_swapped (button, "clicked",
9863                                 G_CALLBACK (gtk_widget_destroy),
9864                                 window);
9865       gtk_widget_set_can_default (button, TRUE);
9866       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9867       gtk_widget_show (button);
9868
9869       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
9870       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9871       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
9872       
9873       label = gtk_label_new ("Font:");
9874       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9875       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9876
9877       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
9878
9879       button = gtk_button_new_with_label ("Some Text");
9880       gtk_widget_override_font (gtk_bin_get_child (GTK_BIN (button)), font_desc);
9881       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9882
9883       label = gtk_label_new ("Foreground:");
9884       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9885       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9886
9887       button = gtk_button_new_with_label ("Some Text");
9888       gtk_widget_override_color (gtk_bin_get_child (GTK_BIN (button)), 0, &red);
9889       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9890
9891       label = gtk_label_new ("Background:");
9892       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9893       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9894
9895       button = gtk_button_new_with_label ("Some Text");
9896       gtk_widget_override_background_color (button, 0, &green);
9897       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9898
9899       label = gtk_label_new ("Text:");
9900       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9901       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9902
9903       entry = gtk_entry_new ();
9904       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9905       gtk_widget_override_color (entry, 0, &blue);
9906       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9907
9908       label = gtk_label_new ("Base:");
9909       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9910       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9911
9912       entry = gtk_entry_new ();
9913       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9914       gtk_widget_override_background_color (entry, 0, &yellow);
9915       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9916
9917       label = gtk_label_new ("Cursor:");
9918       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9919       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9920
9921       entry = gtk_entry_new ();
9922       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9923       gtk_widget_modify_cursor (entry, &red, &red);
9924       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9925
9926       label = gtk_label_new ("Multiple:");
9927       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
9928       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9929
9930       button = gtk_button_new_with_label ("Some Text");
9931
9932       rc_style = gtk_rc_style_new ();
9933
9934       rc_style->font_desc = pango_font_description_copy (font_desc);
9935       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
9936       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
9937       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
9938       rc_style->fg[GTK_STATE_NORMAL] = yellow;
9939       rc_style->bg[GTK_STATE_NORMAL] = blue;
9940       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
9941       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
9942       rc_style->fg[GTK_STATE_ACTIVE] = red;
9943       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
9944       rc_style->xthickness = 5;
9945       rc_style->ythickness = 5;
9946
9947       gtk_widget_modify_style (button, rc_style);
9948       gtk_widget_modify_style (gtk_bin_get_child (GTK_BIN (button)), rc_style);
9949
9950       g_object_unref (rc_style);
9951       
9952       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9953     }
9954   
9955   if (!gtk_widget_get_visible (window))
9956     gtk_widget_show_all (window);
9957   else
9958     gtk_widget_destroy (window);
9959 }
9960 #endif
9961
9962 /*
9963  * Main Window and Exit
9964  */
9965
9966 void
9967 do_exit (GtkWidget *widget, GtkWidget *window)
9968 {
9969   gtk_widget_destroy (window);
9970   gtk_main_quit ();
9971 }
9972
9973 struct {
9974   char *label;
9975   void (*func) (GtkWidget *widget);
9976   gboolean do_not_benchmark;
9977 } buttons[] =
9978 {
9979   { "alpha window", create_alpha_window },
9980   { "big windows", create_big_windows },
9981   { "button box", create_button_box },
9982   { "buttons", create_buttons },
9983   { "check buttons", create_check_buttons },
9984   { "color selection", create_color_selection },
9985   { "composited window", create_composited_window },
9986   { "cursors", create_cursors },
9987   { "dialog", create_dialog },
9988   { "display & screen", create_display_screen, TRUE },
9989   { "entry", create_entry },
9990   { "event box", create_event_box },
9991   { "event watcher", create_event_watcher },
9992   { "expander", create_expander },
9993   { "flipping", create_flipping },
9994   { "focus", create_focus },
9995   { "font selection", create_font_selection },
9996   { "handle box", create_handle_box },
9997   { "image", create_image },
9998   { "key lookup", create_key_lookup },
9999   { "labels", create_labels },
10000   { "layout", create_layout },
10001   { "menus", create_menus },
10002   { "message dialog", create_message_dialog },
10003   { "modal window", create_modal_window, TRUE },
10004   { "notebook", create_notebook },
10005   { "panes", create_panes },
10006   { "paned keyboard", create_paned_keyboard_navigation },
10007   { "pixbuf", create_pixbuf },
10008   { "progress bar", create_progress_bar },
10009   { "properties", create_properties },
10010   { "radio buttons", create_radio_buttons },
10011   { "range controls", create_range_controls },
10012   { "rc file", create_rc_file },
10013   { "reparent", create_reparent },
10014   { "resize grips", create_resize_grips },
10015   { "rotated label", create_rotated_label },
10016   { "rotated text", create_rotated_text },
10017   { "saved position", create_saved_position },
10018   { "scrolled windows", create_scrolled_windows },
10019   { "shapes", create_shapes },
10020   { "size groups", create_size_groups },
10021   { "snapshot", create_snapshot },
10022   { "spinbutton", create_spins },
10023   { "statusbar", create_statusbar },
10024 #if 0
10025   { "styles", create_styles },
10026 #endif
10027   { "test idle", create_idle_test },
10028   { "test mainloop", create_mainloop, TRUE },
10029   { "test scrolling", create_scroll_test },
10030   { "test selection", create_selection_test },
10031   { "test timeout", create_timeout_test },
10032   { "toggle buttons", create_toggle_buttons },
10033   { "toolbar", create_toolbar },
10034   { "tooltips", create_tooltips },
10035   { "WM hints", create_wmhints },
10036   { "window sizing", create_window_sizing },
10037   { "window states", create_window_states }
10038 };
10039 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
10040
10041 void
10042 create_main_window (void)
10043 {
10044   GtkWidget *window;
10045   GtkWidget *box1;
10046   GtkWidget *box2;
10047   GtkWidget *scrolled_window;
10048   GtkWidget *button;
10049   GtkWidget *label;
10050   gchar buffer[64];
10051   GtkWidget *separator;
10052   GdkGeometry geometry;
10053   int i;
10054
10055   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10056   gtk_widget_set_name (window, "main_window");
10057   gtk_window_move (GTK_WINDOW (window), 50, 20);
10058   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
10059
10060   geometry.min_width = -1;
10061   geometry.min_height = -1;
10062   geometry.max_width = -1;
10063   geometry.max_height = G_MAXSHORT;
10064   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
10065                                  &geometry,
10066                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
10067
10068   g_signal_connect (window, "destroy",
10069                     G_CALLBACK (gtk_main_quit),
10070                     NULL);
10071   g_signal_connect (window, "delete-event",
10072                     G_CALLBACK (gtk_false),
10073                     NULL);
10074
10075   box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
10076   gtk_container_add (GTK_CONTAINER (window), box1);
10077
10078   if (gtk_micro_version > 0)
10079     sprintf (buffer,
10080              "Gtk+ v%d.%d.%d",
10081              gtk_get_major_version (),
10082              gtk_get_minor_version (),
10083              gtk_get_micro_version ());
10084   else
10085     sprintf (buffer,
10086              "Gtk+ v%d.%d",
10087              gtk_get_major_version (),
10088              gtk_get_minor_version ());
10089
10090   label = gtk_label_new (buffer);
10091   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
10092   gtk_widget_set_name (label, "testgtk-version-label");
10093
10094   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
10095   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
10096   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
10097                                   GTK_POLICY_NEVER, 
10098                                   GTK_POLICY_AUTOMATIC);
10099   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
10100
10101   box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
10102   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10103   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
10104   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
10105                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
10106   gtk_widget_show (box2);
10107
10108   for (i = 0; i < nbuttons; i++)
10109     {
10110       button = gtk_button_new_with_label (buttons[i].label);
10111       if (buttons[i].func)
10112         g_signal_connect (button, 
10113                           "clicked", 
10114                           G_CALLBACK(buttons[i].func),
10115                           NULL);
10116       else
10117         gtk_widget_set_sensitive (button, FALSE);
10118       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10119     }
10120
10121   separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
10122   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
10123
10124   box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
10125   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10126   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
10127
10128   button = gtk_button_new_with_mnemonic ("_Close");
10129   g_signal_connect (button, "clicked",
10130                     G_CALLBACK (do_exit),
10131                     window);
10132   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10133   gtk_widget_set_can_default (button, TRUE);
10134   gtk_widget_grab_default (button);
10135
10136   gtk_widget_show_all (window);
10137 }
10138
10139 static void
10140 test_init (void)
10141 {
10142   if (g_file_test ("../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
10143     g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
10144 }
10145
10146 static char *
10147 pad (const char *str, int to)
10148 {
10149   static char buf[256];
10150   int len = strlen (str);
10151   int i;
10152
10153   for (i = 0; i < to; i++)
10154     buf[i] = ' ';
10155
10156   buf[to] = '\0';
10157
10158   memcpy (buf, str, len);
10159
10160   return buf;
10161 }
10162
10163 static void
10164 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
10165 {
10166   fn (widget); /* on */
10167   while (g_main_context_iteration (NULL, FALSE));
10168   fn (widget); /* off */
10169   while (g_main_context_iteration (NULL, FALSE));
10170 }
10171
10172 void
10173 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
10174 {
10175   GTimeVal tv0, tv1;
10176   double dt_first;
10177   double dt;
10178   int n;
10179   static gboolean printed_headers = FALSE;
10180
10181   if (!printed_headers) {
10182     g_print ("Test                 Iters      First      Other\n");
10183     g_print ("-------------------- ----- ---------- ----------\n");
10184     printed_headers = TRUE;
10185   }
10186
10187   g_get_current_time (&tv0);
10188   bench_iteration (widget, fn); 
10189   g_get_current_time (&tv1);
10190
10191   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10192         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10193
10194   g_get_current_time (&tv0);
10195   for (n = 0; n < num - 1; n++)
10196     bench_iteration (widget, fn); 
10197   g_get_current_time (&tv1);
10198   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
10199         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
10200
10201   g_print ("%s %5d ", pad (name, 20), num);
10202   if (num > 1)
10203     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
10204   else
10205     g_print ("%10.1f\n", dt_first);
10206 }
10207
10208 void
10209 do_bench (char* what, int num)
10210 {
10211   int i;
10212   GtkWidget *widget;
10213   void (* fn) (GtkWidget *widget);
10214   fn = NULL;
10215   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10216
10217   if (g_ascii_strcasecmp (what, "ALL") == 0)
10218     {
10219       for (i = 0; i < nbuttons; i++)
10220         {
10221           if (!buttons[i].do_not_benchmark)
10222             do_real_bench (widget, buttons[i].func, buttons[i].label, num);
10223         }
10224
10225       return;
10226     }
10227   else
10228     {
10229       for (i = 0; i < nbuttons; i++)
10230         {
10231           if (strcmp (buttons[i].label, what) == 0)
10232             {
10233               fn = buttons[i].func;
10234               break;
10235             }
10236         }
10237       
10238       if (!fn)
10239         g_print ("Can't bench: \"%s\" not found.\n", what);
10240       else
10241         do_real_bench (widget, fn, buttons[i].label, num);
10242     }
10243 }
10244
10245 void 
10246 usage (void)
10247 {
10248   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
10249   exit (1);
10250 }
10251
10252 int
10253 main (int argc, char *argv[])
10254 {
10255   GtkCssProvider *provider, *memory_provider;
10256   GdkDisplay *display;
10257   GdkScreen *screen;
10258   GtkBindingSet *binding_set;
10259   int i;
10260   gboolean done_benchmarks = FALSE;
10261
10262   srand (time (NULL));
10263
10264   test_init ();
10265
10266   g_set_application_name ("GTK+ Test Program");
10267
10268   gtk_init (&argc, &argv);
10269
10270   provider = gtk_css_provider_new ();
10271
10272   /* Check to see if we are being run from the correct
10273    * directory.
10274    */
10275   if (file_exists ("testgtk.css"))
10276     gtk_css_provider_load_from_path (provider, "testgtk.css", NULL);
10277   else if (file_exists ("tests/testgtk.css"))
10278     gtk_css_provider_load_from_path (provider, "tests/testgtk.css", NULL);
10279   else
10280     g_warning ("Couldn't find file \"testgtk.css\".");
10281
10282   display = gdk_display_get_default ();
10283   screen = gdk_display_get_default_screen (display);
10284
10285   gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
10286                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
10287   g_object_unref (provider);
10288
10289   gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
10290                                         GDK_CONTROL_MASK |
10291                                         GDK_MOD1_MASK | 
10292                                         GDK_META_MASK |
10293                                         GDK_SUPER_MASK |
10294                                         GDK_HYPER_MASK |
10295                                         GDK_MOD4_MASK);
10296   /*  benchmarking
10297    */
10298   for (i = 1; i < argc; i++)
10299     {
10300       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
10301         {
10302           int num = 1;
10303           char *nextarg;
10304           char *what;
10305           char *count;
10306           
10307           nextarg = strchr (argv[i], '=');
10308           if (nextarg)
10309             nextarg++;
10310           else
10311             {
10312               i++;
10313               if (i == argc)
10314                 usage ();
10315               nextarg = argv[i];
10316             }
10317
10318           count = strchr (nextarg, ':');
10319           if (count)
10320             {
10321               what = g_strndup (nextarg, count - nextarg);
10322               count++;
10323               num = atoi (count);
10324               if (num <= 0)
10325                 usage ();
10326             }
10327           else
10328             what = g_strdup (nextarg);
10329
10330           do_bench (what, num ? num : 1);
10331           done_benchmarks = TRUE;
10332         }
10333       else
10334         usage ();
10335     }
10336   if (done_benchmarks)
10337     return 0;
10338
10339   /* bindings test
10340    */
10341   binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_WIDGET));
10342   gtk_binding_entry_add_signal (binding_set,
10343                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
10344                                 "debug_msg",
10345                                 1,
10346                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
10347
10348   memory_provider = gtk_css_provider_new ();
10349   gtk_css_provider_load_from_data (memory_provider,
10350                                    "#testgtk-version-label {\n"
10351                                    "  color: #f00;\n"
10352                                    "  font: Sans 18;\n"
10353                                    "}",
10354                                    -1, NULL);
10355   gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (memory_provider),
10356                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
10357
10358   create_main_window ();
10359
10360   gtk_main ();
10361
10362   if (1)
10363     {
10364       while (g_main_context_pending (NULL))
10365         g_main_context_iteration (NULL, FALSE);
10366 #if 0
10367       sleep (1);
10368       while (g_main_context_pending (NULL))
10369         g_main_context_iteration (NULL, FALSE);
10370 #endif
10371     }
10372   return 0;
10373 }