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