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