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