]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
f4a0beee7718709f21d475e12aafe1419798908e
[~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 == 1)
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 == 2)
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     GtkWidget *ok_button, *cancel_button;
3300
3301     csd = gtk_color_chooser_dialog_new ("This is a modal color selection dialog", GTK_WINDOW (parent));
3302
3303     /* Set as modal */
3304     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
3305
3306     g_signal_connect (csd, "destroy",
3307                       G_CALLBACK (cmw_destroy_cb), NULL);
3308     g_signal_connect (csd, "response",
3309                       G_CALLBACK (gtk_widget_destroy), NULL);
3310     
3311     /* wait until destroy calls gtk_main_quit */
3312     gtk_widget_show (csd);    
3313     gtk_main ();
3314 }
3315
3316 static void
3317 cmw_file (GtkWidget *widget, GtkWidget *parent)
3318 {
3319     GtkWidget *fs;
3320
3321     fs = gtk_file_chooser_dialog_new ("This is a modal file selection dialog",
3322       GTK_WINDOW (parent), GTK_FILE_CHOOSER_ACTION_OPEN,
3323       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
3324       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3325       NULL);
3326     gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
3327     gtk_window_set_modal (GTK_WINDOW (fs), TRUE);
3328
3329     g_signal_connect (fs, "destroy",
3330                       G_CALLBACK (cmw_destroy_cb), NULL);
3331     g_signal_connect_swapped (fs, "response",
3332                       G_CALLBACK (gtk_widget_destroy), fs);
3333
3334     /* wait until destroy calls gtk_main_quit */
3335     gtk_widget_show (fs);
3336     gtk_main();
3337 }
3338
3339
3340 static void
3341 create_modal_window (GtkWidget *widget)
3342 {
3343   GtkWidget *window = NULL;
3344   GtkWidget *box1,*box2;
3345   GtkWidget *frame1;
3346   GtkWidget *btnColor,*btnFile,*btnClose;
3347
3348   /* Create modal window (Here you can use any window descendent )*/
3349   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3350   gtk_window_set_screen (GTK_WINDOW (window),
3351                          gtk_widget_get_screen (widget));
3352
3353   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
3354
3355   /* Set window as modal */
3356   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
3357
3358   /* Create widgets */
3359   box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
3360   frame1 = gtk_frame_new ("Standard dialogs in modal form");
3361   box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
3362   gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
3363   btnColor = gtk_button_new_with_label ("Color");
3364   btnFile = gtk_button_new_with_label ("File Selection");
3365   btnClose = gtk_button_new_with_label ("Close");
3366
3367   /* Init widgets */
3368   gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
3369   gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
3370     
3371   /* Pack widgets */
3372   gtk_container_add (GTK_CONTAINER (window), box1);
3373   gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
3374   gtk_container_add (GTK_CONTAINER (frame1), box2);
3375   gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
3376   gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
3377   gtk_box_pack_start (GTK_BOX (box1), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 4);
3378   gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
3379    
3380   /* connect signals */
3381   g_signal_connect_swapped (btnClose, "clicked",
3382                             G_CALLBACK (gtk_widget_destroy), window);
3383
3384   g_signal_connect (window, "destroy",
3385                     G_CALLBACK (cmw_destroy_cb), NULL);
3386   
3387   g_signal_connect (btnColor, "clicked",
3388                     G_CALLBACK (cmw_color), window);
3389   g_signal_connect (btnFile, "clicked",
3390                     G_CALLBACK (cmw_file), window);
3391
3392   /* Show widgets */
3393   gtk_widget_show_all (window);
3394
3395   /* wait until dialog get destroyed */
3396   gtk_main();
3397 }
3398
3399 /*
3400  * GtkMessageDialog
3401  */
3402
3403 static void
3404 make_message_dialog (GdkScreen *screen,
3405                      GtkWidget **dialog,
3406                      GtkMessageType  type,
3407                      GtkButtonsType  buttons,
3408                      guint           default_response)
3409 {
3410   if (*dialog)
3411     {
3412       gtk_widget_destroy (*dialog);
3413
3414       return;
3415     }
3416
3417   *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
3418                                     "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.)");
3419
3420   gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
3421
3422   g_signal_connect_swapped (*dialog,
3423                             "response",
3424                             G_CALLBACK (gtk_widget_destroy),
3425                             *dialog);
3426   
3427   g_signal_connect (*dialog,
3428                     "destroy",
3429                     G_CALLBACK (gtk_widget_destroyed),
3430                     dialog);
3431
3432   gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
3433
3434   gtk_widget_show (*dialog);
3435 }
3436
3437 static void
3438 create_message_dialog (GtkWidget *widget)
3439 {
3440   static GtkWidget *info = NULL;
3441   static GtkWidget *warning = NULL;
3442   static GtkWidget *error = NULL;
3443   static GtkWidget *question = NULL;
3444   GdkScreen *screen = gtk_widget_get_screen (widget);
3445
3446   make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
3447   make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE);
3448   make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
3449   make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_NO);
3450 }
3451
3452 /*
3453  * GtkScrolledWindow
3454  */
3455
3456 static GtkWidget *sw_parent = NULL;
3457 static GtkWidget *sw_float_parent;
3458 static gulong sw_destroyed_handler = 0;
3459
3460 static gboolean
3461 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
3462 {
3463   gtk_widget_reparent (scrollwin, sw_parent);
3464   
3465   g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3466   sw_float_parent = NULL;
3467   sw_parent = NULL;
3468   sw_destroyed_handler = 0;
3469
3470   return FALSE;
3471 }
3472
3473 static void
3474 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
3475 {
3476   gtk_widget_destroy (sw_float_parent);
3477
3478   sw_float_parent = NULL;
3479   sw_parent = NULL;
3480   sw_destroyed_handler = 0;
3481 }
3482
3483 static void
3484 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
3485 {
3486   if (sw_parent)
3487     {
3488       gtk_widget_reparent (scrollwin, sw_parent);
3489       gtk_widget_destroy (sw_float_parent);
3490
3491       g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3492       sw_float_parent = NULL;
3493       sw_parent = NULL;
3494       sw_destroyed_handler = 0;
3495     }
3496   else
3497     {
3498       sw_parent = gtk_widget_get_parent (scrollwin);
3499       sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3500       gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
3501                              gtk_widget_get_screen (widget));
3502       
3503       gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
3504       
3505       gtk_widget_reparent (scrollwin, sw_float_parent);
3506       gtk_widget_show (sw_float_parent);
3507
3508       sw_destroyed_handler =
3509         g_signal_connect (sw_parent, "destroy",
3510                           G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
3511       g_signal_connect (sw_float_parent, "delete_event",
3512                         G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
3513     }
3514 }
3515
3516 static void
3517 create_scrolled_windows (GtkWidget *widget)
3518 {
3519   static GtkWidget *window;
3520   GtkWidget *content_area, *action_area;
3521   GtkWidget *scrolled_window;
3522   GtkWidget *grid;
3523   GtkWidget *button;
3524   char buffer[32];
3525   int i, j;
3526
3527   if (!window)
3528     {
3529       window = gtk_dialog_new ();
3530
3531       gtk_window_set_screen (GTK_WINDOW (window),
3532                              gtk_widget_get_screen (widget));
3533
3534       g_signal_connect (window, "destroy",
3535                         G_CALLBACK (gtk_widget_destroyed),
3536                         &window);
3537
3538       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3539       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
3540
3541       gtk_window_set_title (GTK_WINDOW (window), "dialog");
3542       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3543
3544       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
3545       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
3546       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
3547                                       GTK_POLICY_AUTOMATIC,
3548                                       GTK_POLICY_AUTOMATIC);
3549       gtk_box_pack_start (GTK_BOX (content_area), scrolled_window, TRUE, TRUE, 0);
3550       gtk_widget_show (scrolled_window);
3551
3552       grid = gtk_grid_new ();
3553       gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
3554       gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
3555       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), grid);
3556       gtk_container_set_focus_hadjustment (GTK_CONTAINER (grid),
3557                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3558       gtk_container_set_focus_vadjustment (GTK_CONTAINER (grid),
3559                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3560       gtk_widget_show (grid);
3561
3562       for (i = 0; i < 20; i++)
3563         for (j = 0; j < 20; j++)
3564           {
3565             sprintf (buffer, "button (%d,%d)\n", i, j);
3566             button = gtk_toggle_button_new_with_label (buffer);
3567             gtk_grid_attach (GTK_GRID (grid), button, i, j, 1, 1);
3568             gtk_widget_show (button);
3569           }
3570
3571
3572       button = gtk_button_new_with_label ("Close");
3573       g_signal_connect_swapped (button, "clicked",
3574                                 G_CALLBACK (gtk_widget_destroy),
3575                                 window);
3576       gtk_widget_set_can_default (button, TRUE);
3577       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
3578       gtk_widget_grab_default (button);
3579       gtk_widget_show (button);
3580
3581       button = gtk_button_new_with_label ("Reparent Out");
3582       g_signal_connect (button, "clicked",
3583                         G_CALLBACK (scrolled_windows_remove),
3584                         scrolled_window);
3585       gtk_widget_set_can_default (button, TRUE);
3586       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
3587       gtk_widget_grab_default (button);
3588       gtk_widget_show (button);
3589
3590       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
3591     }
3592
3593   if (!gtk_widget_get_visible (window))
3594     gtk_widget_show (window);
3595   else
3596     gtk_widget_destroy (window);
3597 }
3598
3599 /*
3600  * GtkEntry
3601  */
3602
3603 static void
3604 entry_toggle_frame (GtkWidget *checkbutton,
3605                     GtkWidget *entry)
3606 {
3607    gtk_entry_set_has_frame (GTK_ENTRY(entry),
3608                             gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
3609 }
3610
3611 static void
3612 entry_toggle_sensitive (GtkWidget *checkbutton,
3613                         GtkWidget *entry)
3614 {
3615    gtk_widget_set_sensitive (entry,
3616                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
3617 }
3618
3619 static gboolean
3620 entry_progress_timeout (gpointer data)
3621 {
3622   if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
3623     {
3624       gtk_entry_progress_pulse (GTK_ENTRY (data));
3625     }
3626   else
3627     {
3628       gdouble fraction;
3629
3630       fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
3631
3632       fraction += 0.05;
3633       if (fraction > 1.0001)
3634         fraction = 0.0;
3635
3636       gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
3637     }
3638
3639   return G_SOURCE_CONTINUE;
3640 }
3641
3642 static void
3643 entry_remove_timeout (gpointer data)
3644 {
3645   g_source_remove (GPOINTER_TO_UINT (data));
3646 }
3647
3648 static void
3649 entry_toggle_progress (GtkWidget *checkbutton,
3650                        GtkWidget *entry)
3651 {
3652   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)))
3653     {
3654       guint timeout = gdk_threads_add_timeout (100,
3655                                                entry_progress_timeout,
3656                                                entry);
3657       g_object_set_data_full (G_OBJECT (entry), "timeout-id",
3658                               GUINT_TO_POINTER (timeout),
3659                               entry_remove_timeout);
3660     }
3661   else
3662     {
3663       g_object_set_data (G_OBJECT (entry), "timeout-id",
3664                          GUINT_TO_POINTER (0));
3665
3666       gtk_entry_set_progress_fraction (GTK_ENTRY (entry), 0.0);
3667     }
3668 }
3669
3670 static void
3671 entry_toggle_pulse (GtkWidget *checkbutton,
3672                     GtkWidget *entry)
3673 {
3674   g_object_set_data (G_OBJECT (entry), "progress-pulse",
3675                      GUINT_TO_POINTER ((guint) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))));
3676 }
3677
3678 static void
3679 props_clicked (GtkWidget *button,
3680                GObject   *object)
3681 {
3682   GtkWidget *window = create_prop_editor (object, 0);
3683
3684   gtk_window_set_title (GTK_WINDOW (window), "Object Properties");
3685 }
3686
3687 static void
3688 create_entry (GtkWidget *widget)
3689 {
3690   static GtkWidget *window = NULL;
3691   GtkWidget *box1;
3692   GtkWidget *box2;
3693   GtkWidget *hbox;
3694   GtkWidget *has_frame_check;
3695   GtkWidget *sensitive_check;
3696   GtkWidget *progress_check;
3697   GtkWidget *entry;
3698   GtkComboBoxText *cb;
3699   GtkWidget *cb_entry;
3700   GtkWidget *button;
3701   GtkWidget *separator;
3702
3703   if (!window)
3704     {
3705       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3706       gtk_window_set_screen (GTK_WINDOW (window),
3707                              gtk_widget_get_screen (widget));
3708
3709       g_signal_connect (window, "destroy",
3710                         G_CALLBACK (gtk_widget_destroyed),
3711                         &window);
3712
3713       gtk_window_set_title (GTK_WINDOW (window), "entry");
3714       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3715
3716
3717       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3718       gtk_container_add (GTK_CONTAINER (window), box1);
3719
3720
3721       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3722       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3723       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3724
3725       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
3726       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
3727       
3728       entry = gtk_entry_new ();
3729       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");
3730       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
3731       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3732
3733       button = gtk_button_new_with_mnemonic ("_Props");
3734       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
3735       g_signal_connect (button, "clicked",
3736                         G_CALLBACK (props_clicked),
3737                         entry);
3738
3739       cb = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
3740
3741       gtk_combo_box_text_append_text (cb, "item0");
3742       gtk_combo_box_text_append_text (cb, "item0");
3743       gtk_combo_box_text_append_text (cb, "item1 item1");
3744       gtk_combo_box_text_append_text (cb, "item2 item2 item2");
3745       gtk_combo_box_text_append_text (cb, "item3 item3 item3 item3");
3746       gtk_combo_box_text_append_text (cb, "item4 item4 item4 item4 item4");
3747       gtk_combo_box_text_append_text (cb, "item5 item5 item5 item5 item5 item5");
3748       gtk_combo_box_text_append_text (cb, "item6 item6 item6 item6 item6");
3749       gtk_combo_box_text_append_text (cb, "item7 item7 item7 item7");
3750       gtk_combo_box_text_append_text (cb, "item8 item8 item8");
3751       gtk_combo_box_text_append_text (cb, "item9 item9");
3752
3753       cb_entry = gtk_bin_get_child (GTK_BIN (cb));
3754       gtk_entry_set_text (GTK_ENTRY (cb_entry), "hello world \n\n\n foo");
3755       gtk_editable_select_region (GTK_EDITABLE (cb_entry), 0, -1);
3756       gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (cb), TRUE, TRUE, 0);
3757
3758       sensitive_check = gtk_check_button_new_with_label("Sensitive");
3759       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
3760       g_signal_connect (sensitive_check, "toggled",
3761                         G_CALLBACK (entry_toggle_sensitive), entry);
3762       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
3763
3764       has_frame_check = gtk_check_button_new_with_label("Has Frame");
3765       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
3766       g_signal_connect (has_frame_check, "toggled",
3767                         G_CALLBACK (entry_toggle_frame), entry);
3768       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
3769
3770       progress_check = gtk_check_button_new_with_label("Show Progress");
3771       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
3772       g_signal_connect (progress_check, "toggled",
3773                         G_CALLBACK (entry_toggle_progress), entry);
3774
3775       progress_check = gtk_check_button_new_with_label("Pulse Progress");
3776       gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
3777       g_signal_connect (progress_check, "toggled",
3778                         G_CALLBACK (entry_toggle_pulse), entry);
3779
3780       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
3781       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3782
3783       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3784       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3785       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3786
3787       button = gtk_button_new_with_label ("close");
3788       g_signal_connect_swapped (button, "clicked",
3789                                 G_CALLBACK (gtk_widget_destroy),
3790                                 window);
3791       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3792       gtk_widget_set_can_default (button, TRUE);
3793       gtk_widget_grab_default (button);
3794     }
3795
3796   if (!gtk_widget_get_visible (window))
3797     gtk_widget_show_all (window);
3798   else
3799     gtk_widget_destroy (window);
3800 }
3801
3802 static void
3803 create_expander (GtkWidget *widget)
3804 {
3805   GtkWidget *box1;
3806   GtkWidget *expander;
3807   GtkWidget *hidden;
3808   static GtkWidget *window = NULL;
3809
3810   if (!window)
3811     {
3812       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3813       gtk_window_set_screen (GTK_WINDOW (window),
3814                              gtk_widget_get_screen (widget));
3815       
3816       g_signal_connect (window, "destroy",
3817                         G_CALLBACK (gtk_widget_destroyed),
3818                         &window);
3819       
3820       gtk_window_set_title (GTK_WINDOW (window), "expander");
3821       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3822       
3823       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3824       gtk_container_add (GTK_CONTAINER (window), box1);
3825       
3826       expander = gtk_expander_new ("The Hidden");
3827       
3828       gtk_box_pack_start (GTK_BOX (box1), expander, TRUE, TRUE, 0);
3829       
3830       hidden = gtk_label_new ("Revealed!");
3831       
3832       gtk_container_add (GTK_CONTAINER (expander), hidden);
3833     }
3834   
3835   if (!gtk_widget_get_visible (window))
3836     gtk_widget_show_all (window);
3837   else
3838     gtk_widget_destroy (window);
3839 }
3840
3841
3842 /* GtkEventBox */
3843
3844
3845 static void
3846 event_box_label_pressed (GtkWidget        *widget,
3847                          GdkEventButton   *event,
3848                          gpointer user_data)
3849 {
3850   g_print ("clicked on event box\n");
3851 }
3852
3853 static void
3854 event_box_button_clicked (GtkWidget *widget,
3855                           GtkWidget *button,
3856                           gpointer user_data)
3857 {
3858   g_print ("pushed button\n");
3859 }
3860
3861 static void
3862 event_box_toggle_visible_window (GtkWidget *checkbutton,
3863                                  GtkEventBox *event_box)
3864 {
3865   gtk_event_box_set_visible_window (event_box,
3866                                     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
3867 }
3868
3869 static void
3870 event_box_toggle_above_child (GtkWidget *checkbutton,
3871                               GtkEventBox *event_box)
3872 {
3873   gtk_event_box_set_above_child (event_box,
3874                                  gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
3875 }
3876
3877 static void
3878 create_event_box (GtkWidget *widget)
3879 {
3880   static GtkWidget *window = NULL;
3881   GtkWidget *box1;
3882   GtkWidget *box2;
3883   GtkWidget *hbox;
3884   GtkWidget *vbox;
3885   GtkWidget *button;
3886   GtkWidget *separator;
3887   GtkWidget *event_box;
3888   GtkWidget *label;
3889   GtkWidget *visible_window_check;
3890   GtkWidget *above_child_check;
3891   GdkRGBA color;
3892
3893   if (!window)
3894     {
3895       color.red = 0;
3896       color.blue = 1;
3897       color.green = 0;
3898       color.alpha = 1;
3899       
3900       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3901       gtk_window_set_screen (GTK_WINDOW (window),
3902                              gtk_widget_get_screen (widget));
3903
3904       g_signal_connect (window, "destroy",
3905                         G_CALLBACK (gtk_widget_destroyed),
3906                         &window);
3907
3908       gtk_window_set_title (GTK_WINDOW (window), "event box");
3909       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3910
3911       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3912       gtk_container_add (GTK_CONTAINER (window), box1);
3913       gtk_widget_override_background_color (window, 0, &color);
3914
3915       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
3916       gtk_box_pack_start (GTK_BOX (box1), hbox, TRUE, FALSE, 0);
3917       
3918       event_box = gtk_event_box_new ();
3919       gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, FALSE, 0);
3920
3921       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3922       gtk_container_add (GTK_CONTAINER (event_box), vbox);
3923       g_signal_connect (event_box, "button_press_event",
3924                         G_CALLBACK (event_box_label_pressed),
3925                         NULL);
3926       
3927       label = gtk_label_new ("Click on this label");
3928       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
3929
3930       button = gtk_button_new_with_label ("button in eventbox");
3931       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, FALSE, 0);
3932       g_signal_connect (button, "clicked",
3933                         G_CALLBACK (event_box_button_clicked),
3934                         NULL);
3935       
3936
3937       visible_window_check = gtk_check_button_new_with_label("Visible Window");
3938       gtk_box_pack_start (GTK_BOX (box1), visible_window_check, FALSE, TRUE, 0);
3939       g_signal_connect (visible_window_check, "toggled",
3940                         G_CALLBACK (event_box_toggle_visible_window), event_box);
3941       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visible_window_check), FALSE);
3942       
3943       above_child_check = gtk_check_button_new_with_label("Above Child");
3944       gtk_box_pack_start (GTK_BOX (box1), above_child_check, FALSE, TRUE, 0);
3945       g_signal_connect (above_child_check, "toggled",
3946                         G_CALLBACK (event_box_toggle_above_child), event_box);
3947       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (above_child_check), FALSE);
3948       
3949       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
3950       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3951
3952       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3953       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3954       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3955
3956       button = gtk_button_new_with_label ("close");
3957       g_signal_connect_swapped (button, "clicked",
3958                                 G_CALLBACK (gtk_widget_destroy),
3959                                 window);
3960       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3961       gtk_widget_set_can_default (button, TRUE);
3962       gtk_widget_grab_default (button);
3963     }
3964
3965   if (!gtk_widget_get_visible (window))
3966     gtk_widget_show_all (window);
3967   else
3968     gtk_widget_destroy (window);
3969 }
3970
3971
3972 /*
3973  * GtkSizeGroup
3974  */
3975
3976 #define SIZE_GROUP_INITIAL_SIZE 50
3977
3978 static void
3979 size_group_hsize_changed (GtkSpinButton *spin_button,
3980                           GtkWidget     *button)
3981 {
3982   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
3983                                gtk_spin_button_get_value_as_int (spin_button),
3984                                -1);
3985 }
3986
3987 static void
3988 size_group_vsize_changed (GtkSpinButton *spin_button,
3989                           GtkWidget     *button)
3990 {
3991   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
3992                                -1,
3993                                gtk_spin_button_get_value_as_int (spin_button));
3994 }
3995
3996 static GtkWidget *
3997 create_size_group_window (GdkScreen    *screen,
3998                           GtkSizeGroup *master_size_group)
3999 {
4000   GtkWidget *content_area;
4001   GtkWidget *window;
4002   GtkWidget *grid;
4003   GtkWidget *main_button;
4004   GtkWidget *button;
4005   GtkWidget *spin_button;
4006   GtkWidget *hbox;
4007   GtkSizeGroup *hgroup1;
4008   GtkSizeGroup *hgroup2;
4009   GtkSizeGroup *vgroup1;
4010   GtkSizeGroup *vgroup2;
4011
4012   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4013                                         NULL, 0,
4014                                         GTK_STOCK_CLOSE,
4015                                         GTK_RESPONSE_NONE,
4016                                         NULL);
4017
4018   gtk_window_set_screen (GTK_WINDOW (window), screen);
4019
4020   gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
4021
4022   g_signal_connect (window, "response",
4023                     G_CALLBACK (gtk_widget_destroy),
4024                     NULL);
4025
4026   content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
4027
4028   grid = gtk_grid_new ();
4029   gtk_box_pack_start (GTK_BOX (content_area), grid, TRUE, TRUE, 0);
4030
4031   gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
4032   gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
4033   gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
4034   gtk_widget_set_size_request (grid, 250, 250);
4035
4036   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4037   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4038   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4039   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4040
4041   main_button = gtk_button_new_with_label ("X");
4042   gtk_widget_set_hexpand (main_button, TRUE);
4043   gtk_widget_set_vexpand (main_button, TRUE);
4044   gtk_widget_set_halign (main_button, GTK_ALIGN_CENTER);
4045   gtk_widget_set_valign (main_button, GTK_ALIGN_CENTER);
4046   gtk_grid_attach (GTK_GRID (grid), main_button, 0, 0, 1, 1);
4047   
4048   gtk_size_group_add_widget (master_size_group, main_button);
4049   gtk_size_group_add_widget (hgroup1, main_button);
4050   gtk_size_group_add_widget (vgroup1, main_button);
4051   gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (main_button)),
4052                                SIZE_GROUP_INITIAL_SIZE,
4053                                SIZE_GROUP_INITIAL_SIZE);
4054
4055   button = gtk_button_new ();
4056   gtk_widget_set_hexpand (button, TRUE);
4057   gtk_widget_set_vexpand (button, TRUE);
4058   gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4059   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4060   gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
4061
4062   gtk_size_group_add_widget (vgroup1, button);
4063   gtk_size_group_add_widget (vgroup2, button);
4064
4065   button = gtk_button_new ();
4066   gtk_widget_set_hexpand (button, TRUE);
4067   gtk_widget_set_vexpand (button, TRUE);
4068   gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4069   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4070   gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1);
4071
4072   gtk_size_group_add_widget (hgroup1, button);
4073   gtk_size_group_add_widget (hgroup2, button);
4074
4075   button = gtk_button_new ();
4076   gtk_widget_set_hexpand (button, TRUE);
4077   gtk_widget_set_vexpand (button, TRUE);
4078   gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4079   gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4080   gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1);
4081
4082   gtk_size_group_add_widget (hgroup2, button);
4083   gtk_size_group_add_widget (vgroup2, button);
4084
4085   g_object_unref (hgroup1);
4086   g_object_unref (hgroup2);
4087   g_object_unref (vgroup1);
4088   g_object_unref (vgroup2);
4089   
4090   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
4091   gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
4092   
4093   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4094   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4095   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4096   g_signal_connect (spin_button, "value_changed",
4097                     G_CALLBACK (size_group_hsize_changed), main_button);
4098
4099   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4100   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4101   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4102   g_signal_connect (spin_button, "value_changed",
4103                     G_CALLBACK (size_group_vsize_changed), main_button);
4104
4105   return window;
4106 }
4107
4108 static void
4109 create_size_groups (GtkWidget *widget)
4110 {
4111   static GtkWidget *window1 = NULL;
4112   static GtkWidget *window2 = NULL;
4113   static GtkSizeGroup *master_size_group;
4114
4115   if (!master_size_group)
4116     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4117
4118   if (!window1)
4119     {
4120       window1 = create_size_group_window (gtk_widget_get_screen (widget),
4121                                           master_size_group);
4122
4123       g_signal_connect (window1, "destroy",
4124                         G_CALLBACK (gtk_widget_destroyed),
4125                         &window1);
4126     }
4127
4128   if (!window2)
4129     {
4130       window2 = create_size_group_window (gtk_widget_get_screen (widget),
4131                                           master_size_group);
4132
4133       g_signal_connect (window2, "destroy",
4134                         G_CALLBACK (gtk_widget_destroyed),
4135                         &window2);
4136     }
4137
4138   if (gtk_widget_get_visible (window1) && gtk_widget_get_visible (window2))
4139     {
4140       gtk_widget_destroy (window1);
4141       gtk_widget_destroy (window2);
4142     }
4143   else
4144     {
4145       if (!gtk_widget_get_visible (window1))
4146         gtk_widget_show_all (window1);
4147       if (!gtk_widget_get_visible (window2))
4148         gtk_widget_show_all (window2);
4149     }
4150 }
4151
4152 /*
4153  * GtkSpinButton
4154  */
4155
4156 static GtkWidget *spinner1;
4157
4158 static void
4159 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4160 {
4161   gtk_spin_button_set_snap_to_ticks (spin,
4162                                      gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
4163 }
4164
4165 static void
4166 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4167 {
4168   gtk_spin_button_set_numeric (spin,
4169                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
4170 }
4171
4172 static void
4173 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4174 {
4175   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4176                               gtk_spin_button_get_value_as_int (spin));
4177 }
4178
4179 static void
4180 get_value (GtkWidget *widget, gpointer data)
4181 {
4182   gchar buf[32];
4183   GtkLabel *label;
4184   GtkSpinButton *spin;
4185
4186   spin = GTK_SPIN_BUTTON (spinner1);
4187   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4188   if (GPOINTER_TO_INT (data) == 1)
4189     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4190   else
4191     sprintf (buf, "%0.*f",
4192              gtk_spin_button_get_digits (spin),
4193              gtk_spin_button_get_value (spin));
4194
4195   gtk_label_set_text (label, buf);
4196 }
4197
4198 static void
4199 get_spin_value (GtkWidget *widget, gpointer data)
4200 {
4201   gchar *buffer;
4202   GtkLabel *label;
4203   GtkSpinButton *spin;
4204
4205   spin = GTK_SPIN_BUTTON (widget);
4206   label = GTK_LABEL (data);
4207
4208   buffer = g_strdup_printf ("%0.*f",
4209                             gtk_spin_button_get_digits (spin),
4210                             gtk_spin_button_get_value (spin));
4211   gtk_label_set_text (label, buffer);
4212
4213   g_free (buffer);
4214 }
4215
4216 static gint
4217 spin_button_time_output_func (GtkSpinButton *spin_button)
4218 {
4219   GtkAdjustment *adjustment;
4220   static gchar buf[6];
4221   gdouble hours;
4222   gdouble minutes;
4223
4224   adjustment = gtk_spin_button_get_adjustment (spin_button);
4225   hours = gtk_adjustment_get_value (adjustment) / 60.0;
4226   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4227   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4228   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4229     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4230   return TRUE;
4231 }
4232
4233 static gint
4234 spin_button_month_input_func (GtkSpinButton *spin_button,
4235                               gdouble       *new_val)
4236 {
4237   gint i;
4238   static gchar *month[12] = { "January", "February", "March", "April",
4239                               "May", "June", "July", "August",
4240                               "September", "October", "November", "December" };
4241   gchar *tmp1, *tmp2;
4242   gboolean found = FALSE;
4243
4244   for (i = 1; i <= 12; i++)
4245     {
4246       tmp1 = g_ascii_strup (month[i - 1], -1);
4247       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4248       if (strstr (tmp1, tmp2) == tmp1)
4249         found = TRUE;
4250       g_free (tmp1);
4251       g_free (tmp2);
4252       if (found)
4253         break;
4254     }
4255   if (!found)
4256     {
4257       *new_val = 0.0;
4258       return GTK_INPUT_ERROR;
4259     }
4260   *new_val = (gdouble) i;
4261   return TRUE;
4262 }
4263
4264 static gint
4265 spin_button_month_output_func (GtkSpinButton *spin_button)
4266 {
4267   GtkAdjustment *adjustment;
4268   gdouble value;
4269   gint i;
4270   static gchar *month[12] = { "January", "February", "March", "April",
4271                               "May", "June", "July", "August", "September",
4272                               "October", "November", "December" };
4273
4274   adjustment = gtk_spin_button_get_adjustment (spin_button);
4275   value = gtk_adjustment_get_value (adjustment);
4276   for (i = 1; i <= 12; i++)
4277     if (fabs (value - (double)i) < 1e-5)
4278       {
4279         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4280           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4281       }
4282   return TRUE;
4283 }
4284
4285 static gint
4286 spin_button_hex_input_func (GtkSpinButton *spin_button,
4287                             gdouble       *new_val)
4288 {
4289   const gchar *buf;
4290   gchar *err;
4291   gdouble res;
4292
4293   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4294   res = strtol(buf, &err, 16);
4295   *new_val = res;
4296   if (*err)
4297     return GTK_INPUT_ERROR;
4298   else
4299     return TRUE;
4300 }
4301
4302 static gint
4303 spin_button_hex_output_func (GtkSpinButton *spin_button)
4304 {
4305   GtkAdjustment *adjustment;
4306   static gchar buf[7];
4307   gint val;
4308
4309   adjustment = gtk_spin_button_get_adjustment (spin_button);
4310   val = (gint) gtk_adjustment_get_value (adjustment);
4311   if (fabs (val) < 1e-5)
4312     sprintf (buf, "0x00");
4313   else
4314     sprintf (buf, "0x%.2X", val);
4315   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4316     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4317   return TRUE;
4318 }
4319
4320 static void
4321 create_spins (GtkWidget *widget)
4322 {
4323   static GtkWidget *window = NULL;
4324   GtkWidget *frame;
4325   GtkWidget *hbox;
4326   GtkWidget *main_vbox;
4327   GtkWidget *vbox;
4328   GtkWidget *vbox2;
4329   GtkWidget *spinner2;
4330   GtkWidget *spinner;
4331   GtkWidget *button;
4332   GtkWidget *label;
4333   GtkWidget *val_label;
4334   GtkAdjustment *adjustment;
4335
4336   if (!window)
4337     {
4338       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4339       gtk_window_set_screen (GTK_WINDOW (window),
4340                              gtk_widget_get_screen (widget));
4341       
4342       g_signal_connect (window, "destroy",
4343                         G_CALLBACK (gtk_widget_destroyed),
4344                         &window);
4345       
4346       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4347       
4348       main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
4349       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4350       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4351       
4352       frame = gtk_frame_new ("Not accelerated");
4353       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4354       
4355       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4356       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4357       gtk_container_add (GTK_CONTAINER (frame), vbox);
4358       
4359       /* Time, month, hex spinners */
4360       
4361       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4362       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4363       
4364       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4365       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4366       
4367       label = gtk_label_new ("Time :");
4368       gtk_widget_set_halign (label, GTK_ALIGN_START);
4369       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4370       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4371
4372       adjustment = gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4373       spinner = gtk_spin_button_new (adjustment, 0, 0);
4374       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4375       g_signal_connect (spinner,
4376                         "output",
4377                         G_CALLBACK (spin_button_time_output_func),
4378                         NULL);
4379       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4380       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 5);
4381       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4382
4383       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4384       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4385       
4386       label = gtk_label_new ("Month :");
4387       gtk_widget_set_halign (label, GTK_ALIGN_START);
4388       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4389       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4390
4391       adjustment = gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4392                                                   5.0, 0.0);
4393       spinner = gtk_spin_button_new (adjustment, 0, 0);
4394       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4395                                          GTK_UPDATE_IF_VALID);
4396       g_signal_connect (spinner,
4397                         "input",
4398                         G_CALLBACK (spin_button_month_input_func),
4399                         NULL);
4400       g_signal_connect (spinner,
4401                         "output",
4402                         G_CALLBACK (spin_button_month_output_func),
4403                         NULL);
4404       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4405       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 9);
4406       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4407       
4408       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4409       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4410
4411       label = gtk_label_new ("Hex :");
4412       gtk_widget_set_halign (label, GTK_ALIGN_START);
4413       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4414       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4415
4416       adjustment = gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4417       spinner = gtk_spin_button_new (adjustment, 0, 0);
4418       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4419       g_signal_connect (spinner,
4420                         "input",
4421                         G_CALLBACK (spin_button_hex_input_func),
4422                         NULL);
4423       g_signal_connect (spinner,
4424                         "output",
4425                         G_CALLBACK (spin_button_hex_output_func),
4426                         NULL);
4427       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4428       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 4);
4429       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4430
4431       frame = gtk_frame_new ("Accelerated");
4432       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4433   
4434       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4435       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4436       gtk_container_add (GTK_CONTAINER (frame), vbox);
4437       
4438       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4439       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4440       
4441       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4442       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4443       
4444       label = gtk_label_new ("Value :");
4445       gtk_widget_set_halign (label, GTK_ALIGN_START);
4446       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4447       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4448
4449       adjustment = gtk_adjustment_new (0.0, -10000.0, 10000.0,
4450                                                   0.5, 100.0, 0.0);
4451       spinner1 = gtk_spin_button_new (adjustment, 1.0, 2);
4452       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4453       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4454
4455       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4456       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4457
4458       label = gtk_label_new ("Digits :");
4459       gtk_widget_set_halign (label, GTK_ALIGN_START);
4460       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4461       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4462
4463       adjustment = gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4464       spinner2 = gtk_spin_button_new (adjustment, 0.0, 0);
4465       g_signal_connect (adjustment, "value_changed",
4466                         G_CALLBACK (change_digits),
4467                         spinner2);
4468       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4469
4470       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4471       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4472
4473       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4474       g_signal_connect (button, "clicked",
4475                         G_CALLBACK (toggle_snap),
4476                         spinner1);
4477       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4478       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4479
4480       button = gtk_check_button_new_with_label ("Numeric only input mode");
4481       g_signal_connect (button, "clicked",
4482                         G_CALLBACK (toggle_numeric),
4483                         spinner1);
4484       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4485       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4486
4487       val_label = gtk_label_new ("");
4488
4489       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4490       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4491
4492       button = gtk_button_new_with_label ("Value as Int");
4493       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4494       g_signal_connect (button, "clicked",
4495                         G_CALLBACK (get_value),
4496                         GINT_TO_POINTER (1));
4497       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4498
4499       button = gtk_button_new_with_label ("Value as Float");
4500       g_object_set_data (G_OBJECT (button), "user_data", val_label);
4501       g_signal_connect (button, "clicked",
4502                         G_CALLBACK (get_value),
4503                         GINT_TO_POINTER (2));
4504       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4505
4506       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4507       gtk_label_set_text (GTK_LABEL (val_label), "0");
4508
4509       frame = gtk_frame_new ("Using Convenience Constructor");
4510       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4511   
4512       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4513       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4514       gtk_container_add (GTK_CONTAINER (frame), hbox);
4515       
4516       val_label = gtk_label_new ("0.0");
4517
4518       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4519       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4520       g_signal_connect (spinner, "value_changed",
4521                         G_CALLBACK (get_spin_value), val_label);
4522       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4523       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4524
4525       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4526       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4527   
4528       button = gtk_button_new_with_label ("Close");
4529       g_signal_connect_swapped (button, "clicked",
4530                                 G_CALLBACK (gtk_widget_destroy),
4531                                 window);
4532       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4533     }
4534
4535   if (!gtk_widget_get_visible (window))
4536     gtk_widget_show_all (window);
4537   else
4538     gtk_widget_destroy (window);
4539 }
4540
4541
4542 /*
4543  * Cursors
4544  */
4545
4546 static gint
4547 cursor_draw (GtkWidget *widget,
4548              cairo_t   *cr,
4549              gpointer   user_data)
4550 {
4551   int width, height;
4552   GtkStyleContext *context;
4553   GdkRGBA bg;
4554
4555   width = gtk_widget_get_allocated_width (widget);
4556   height = gtk_widget_get_allocated_height (widget);
4557
4558   cairo_set_source_rgb (cr, 1, 1, 1);
4559   cairo_rectangle (cr, 0, 0, width, height / 2);
4560   cairo_fill (cr);
4561
4562   cairo_set_source_rgb (cr, 0, 0, 0);
4563   cairo_rectangle (cr, 0, height / 2, width, height / 2);
4564   cairo_fill (cr);
4565
4566   context = gtk_widget_get_style_context (widget);
4567   gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg);
4568   gdk_cairo_set_source_rgba (cr, &bg);
4569   cairo_rectangle (cr, width / 3, height / 3, width / 3, height / 3);
4570   cairo_fill (cr);
4571
4572   return TRUE;
4573 }
4574
4575 static void
4576 set_cursor (GtkWidget *spinner,
4577             GtkWidget *widget)
4578 {
4579   guint c;
4580   GdkCursor *cursor;
4581   GtkWidget *label;
4582   GEnumClass *class;
4583   GEnumValue *vals;
4584
4585   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
4586   c &= 0xfe;
4587
4588   label = g_object_get_data (G_OBJECT (spinner), "user_data");
4589   
4590   class = g_type_class_ref (GDK_TYPE_CURSOR_TYPE);
4591   vals = class->values;
4592
4593   while (vals && vals->value != c)
4594     vals++;
4595   if (vals)
4596     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
4597   else
4598     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
4599
4600   g_type_class_unref (class);
4601
4602   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
4603   gdk_window_set_cursor (gtk_widget_get_window (widget),
4604                          cursor);
4605   g_object_unref (cursor);
4606 }
4607
4608 static gint
4609 cursor_event (GtkWidget          *widget,
4610               GdkEvent           *event,
4611               GtkSpinButton      *spinner)
4612 {
4613   if ((event->type == GDK_BUTTON_PRESS) &&
4614       ((event->button.button == GDK_BUTTON_PRIMARY) ||
4615        (event->button.button == GDK_BUTTON_SECONDARY)))
4616     {
4617       gtk_spin_button_spin (spinner, event->button.button == GDK_BUTTON_PRIMARY ?
4618                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
4619       return TRUE;
4620     }
4621
4622   return FALSE;
4623 }
4624
4625 #ifdef GDK_WINDOWING_X11
4626 #include "x11/gdkx.h"
4627
4628 static void
4629 change_cursor_theme (GtkWidget *widget,
4630                      gpointer   data)
4631 {
4632   const gchar *theme;
4633   gint size;
4634   GList *children;
4635
4636   children = gtk_container_get_children (GTK_CONTAINER (data));
4637
4638   theme = gtk_entry_get_text (GTK_ENTRY (children->next->data));
4639   size = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (children->next->next->data));
4640
4641   g_list_free (children);
4642
4643   gdk_x11_display_set_cursor_theme (gtk_widget_get_display (widget),
4644                                     theme, size);
4645 }
4646 #endif
4647
4648
4649 static void
4650 create_cursors (GtkWidget *widget)
4651 {
4652   static GtkWidget *window = NULL;
4653   GtkWidget *frame;
4654   GtkWidget *hbox;
4655   GtkWidget *main_vbox;
4656   GtkWidget *vbox;
4657   GtkWidget *darea;
4658   GtkWidget *spinner;
4659   GtkWidget *button;
4660   GtkWidget *label;
4661   GtkWidget *any;
4662   GtkAdjustment *adjustment;
4663   GtkWidget *entry;
4664   GtkWidget *size;  
4665
4666   if (!window)
4667     {
4668       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4669       gtk_window_set_screen (GTK_WINDOW (window), 
4670                              gtk_widget_get_screen (widget));
4671       
4672       g_signal_connect (window, "destroy",
4673                         G_CALLBACK (gtk_widget_destroyed),
4674                         &window);
4675       
4676       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
4677       
4678       main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
4679       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
4680       gtk_container_add (GTK_CONTAINER (window), main_vbox);
4681
4682       vbox =
4683         g_object_new (GTK_TYPE_BOX,
4684                       "orientation", GTK_ORIENTATION_VERTICAL,
4685                         "GtkBox::homogeneous", FALSE,
4686                         "GtkBox::spacing", 5,
4687                         "GtkContainer::border_width", 10,
4688                         "GtkWidget::parent", main_vbox,
4689                         "GtkWidget::visible", TRUE,
4690                         NULL);
4691
4692 #ifdef GDK_WINDOWING_X11
4693       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4694       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4695       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4696
4697       label = gtk_label_new ("Cursor Theme : ");
4698       gtk_widget_set_halign (label, GTK_ALIGN_START);
4699       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4700       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4701
4702       entry = gtk_entry_new ();
4703       gtk_entry_set_text (GTK_ENTRY (entry), "default");
4704       gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
4705
4706       size = gtk_spin_button_new_with_range (1.0, 64.0, 1.0);
4707       gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), 24.0);
4708       gtk_box_pack_start (GTK_BOX (hbox), size, TRUE, TRUE, 0);
4709       
4710       g_signal_connect (entry, "changed", 
4711                         G_CALLBACK (change_cursor_theme), hbox);
4712       g_signal_connect (size, "changed", 
4713                         G_CALLBACK (change_cursor_theme), hbox);
4714 #endif
4715
4716       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4717       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4718       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4719
4720       label = gtk_label_new ("Cursor Value : ");
4721       gtk_widget_set_halign (label, GTK_ALIGN_START);
4722       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4723       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4724
4725       adjustment = gtk_adjustment_new (0,
4726                                 0, 152,
4727                                 2,
4728                                 10, 0);
4729       spinner = gtk_spin_button_new (adjustment, 0, 0);
4730       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
4731
4732       frame =
4733         g_object_new (gtk_frame_get_type (),
4734                         "GtkFrame::label_xalign", 0.5,
4735                         "GtkFrame::label", "Cursor Area",
4736                         "GtkContainer::border_width", 10,
4737                         "GtkWidget::parent", vbox,
4738                         "GtkWidget::visible", TRUE,
4739                         NULL);
4740
4741       darea = gtk_drawing_area_new ();
4742       gtk_widget_set_size_request (darea, 80, 80);
4743       gtk_container_add (GTK_CONTAINER (frame), darea);
4744       g_signal_connect (darea,
4745                         "draw",
4746                         G_CALLBACK (cursor_draw),
4747                         NULL);
4748       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
4749       g_signal_connect (darea,
4750                         "button_press_event",
4751                         G_CALLBACK (cursor_event),
4752                         spinner);
4753       gtk_widget_show (darea);
4754
4755       g_signal_connect (spinner, "changed",
4756                         G_CALLBACK (set_cursor),
4757                         darea);
4758
4759       label = g_object_new (GTK_TYPE_LABEL,
4760                               "visible", TRUE,
4761                               "label", "XXX",
4762                               "parent", vbox,
4763                               NULL);
4764       gtk_container_child_set (GTK_CONTAINER (vbox), label,
4765                                "expand", FALSE,
4766                                NULL);
4767       g_object_set_data (G_OBJECT (spinner), "user_data", label);
4768
4769       any = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
4770       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
4771   
4772       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4773       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
4774       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4775
4776       button = gtk_button_new_with_label ("Close");
4777       g_signal_connect_swapped (button, "clicked",
4778                                 G_CALLBACK (gtk_widget_destroy),
4779                                 window);
4780       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4781
4782       gtk_widget_show_all (window);
4783
4784       set_cursor (spinner, darea);
4785     }
4786   else
4787     gtk_widget_destroy (window);
4788 }
4789
4790 /*
4791  * GtkColorSelection
4792  */
4793
4794 void
4795 create_color_selection (GtkWidget *widget)
4796 {
4797   static GtkWidget *window = NULL;
4798
4799   if (!window)
4800     {
4801       GtkWidget *picker;
4802       GtkWidget *hbox;
4803       GtkWidget *label;
4804       GtkWidget *button;
4805       
4806       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4807       gtk_window_set_screen (GTK_WINDOW (window), 
4808                              gtk_widget_get_screen (widget));
4809                              
4810       g_signal_connect (window, "destroy",
4811                         G_CALLBACK (gtk_widget_destroyed),
4812                         &window);
4813
4814       gtk_window_set_title (GTK_WINDOW (window), "GtkColorButton");
4815       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4816
4817       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
4818       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
4819       gtk_container_add (GTK_CONTAINER (window), hbox);
4820       
4821       label = gtk_label_new ("Pick a color");
4822       gtk_container_add (GTK_CONTAINER (hbox), label);
4823
4824       picker = gtk_color_button_new ();
4825       gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (picker), TRUE);
4826       gtk_container_add (GTK_CONTAINER (hbox), picker);
4827
4828       button = gtk_button_new_with_mnemonic ("_Props");
4829       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
4830       g_signal_connect (button, "clicked",
4831                         G_CALLBACK (props_clicked),
4832                         picker);
4833     }
4834
4835   if (!gtk_widget_get_visible (window))
4836     gtk_widget_show_all (window);
4837   else
4838     gtk_widget_destroy (window);
4839 }
4840
4841 void
4842 flipping_toggled_cb (GtkWidget *widget, gpointer data)
4843 {
4844   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
4845   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
4846
4847   gtk_widget_set_default_direction (new_direction);
4848 }
4849
4850 static void
4851 orientable_toggle_orientation (GtkOrientable *orientable)
4852 {
4853   GtkOrientation orientation;
4854
4855   orientation = gtk_orientable_get_orientation (orientable);
4856   gtk_orientable_set_orientation (orientable,
4857                                   orientation == GTK_ORIENTATION_HORIZONTAL ?
4858                                   GTK_ORIENTATION_VERTICAL :
4859                                   GTK_ORIENTATION_HORIZONTAL);
4860
4861   if (GTK_IS_CONTAINER (orientable))
4862     {
4863       GList *children;
4864       GList *child;
4865
4866       children = gtk_container_get_children (GTK_CONTAINER (orientable));
4867
4868       for (child = children; child; child = child->next)
4869         {
4870           if (GTK_IS_ORIENTABLE (child->data))
4871             orientable_toggle_orientation (child->data);
4872         }
4873
4874       g_list_free (children);
4875     }
4876 }
4877
4878 void
4879 flipping_orientation_toggled_cb (GtkWidget *widget, gpointer data)
4880 {
4881   GtkWidget *content_area;
4882   GtkWidget *toplevel;
4883
4884   toplevel = gtk_widget_get_toplevel (widget);
4885   content_area = gtk_dialog_get_content_area (GTK_DIALOG (toplevel));
4886   orientable_toggle_orientation (GTK_ORIENTABLE (content_area));
4887 }
4888
4889 static void
4890 set_direction_recurse (GtkWidget *widget,
4891                        gpointer   data)
4892 {
4893   GtkTextDirection *dir = data;
4894   
4895   gtk_widget_set_direction (widget, *dir);
4896   if (GTK_IS_CONTAINER (widget))
4897     gtk_container_foreach (GTK_CONTAINER (widget),
4898                            set_direction_recurse,
4899                            data);
4900 }
4901
4902 static GtkWidget *
4903 create_forward_back (const char       *title,
4904                      GtkTextDirection  text_dir)
4905 {
4906   GtkWidget *frame = gtk_frame_new (title);
4907   GtkWidget *bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
4908   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
4909   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
4910
4911   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
4912   
4913   gtk_container_add (GTK_CONTAINER (frame), bbox);
4914   gtk_container_add (GTK_CONTAINER (bbox), back_button);
4915   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
4916
4917   set_direction_recurse (frame, &text_dir);
4918
4919   return frame;
4920 }
4921
4922 void
4923 create_flipping (GtkWidget *widget)
4924 {
4925   static GtkWidget *window = NULL;
4926   GtkWidget *check_button, *button;
4927   GtkWidget *action_area, *content_area;
4928
4929   if (!window)
4930     {
4931       window = gtk_dialog_new ();
4932
4933       gtk_window_set_screen (GTK_WINDOW (window),
4934                              gtk_widget_get_screen (widget));
4935
4936       g_signal_connect (window, "destroy",
4937                         G_CALLBACK (gtk_widget_destroyed),
4938                         &window);
4939
4940       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
4941       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
4942
4943       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
4944
4945       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
4946       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
4947       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
4948
4949       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
4950         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
4951
4952       g_signal_connect (check_button, "toggled",
4953                         G_CALLBACK (flipping_toggled_cb), NULL);
4954
4955       check_button = gtk_check_button_new_with_label ("Toggle orientation of all boxes");
4956       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
4957       gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
4958
4959       g_signal_connect (check_button, "toggled",
4960                         G_CALLBACK (flipping_orientation_toggled_cb), NULL);
4961
4962       gtk_box_pack_start (GTK_BOX (content_area),
4963                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
4964                           TRUE, TRUE, 0);
4965
4966       gtk_box_pack_start (GTK_BOX (content_area),
4967                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
4968                           TRUE, TRUE, 0);
4969
4970       gtk_box_pack_start (GTK_BOX (content_area),
4971                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
4972                           TRUE, TRUE, 0);
4973
4974       button = gtk_button_new_with_label ("Close");
4975       g_signal_connect_swapped (button, "clicked",
4976                                 G_CALLBACK (gtk_widget_destroy), window);
4977       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
4978     }
4979   
4980   if (!gtk_widget_get_visible (window))
4981     gtk_widget_show_all (window);
4982   else
4983     gtk_widget_destroy (window);
4984 }
4985
4986 /*
4987  * Focus test
4988  */
4989
4990 static GtkWidget*
4991 make_focus_table (GList **list)
4992 {
4993   GtkWidget *grid;
4994   gint i, j;
4995   
4996   grid = gtk_grid_new ();
4997
4998   gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
4999   gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
5000
5001   for (i = 0; i < 5; i++)
5002     {
5003       for (j = 0; j < 5; j++)
5004         {
5005           GtkWidget *widget;
5006           
5007           if ((i + j) % 2)
5008             widget = gtk_entry_new ();
5009           else
5010             widget = gtk_button_new_with_label ("Foo");
5011
5012           *list = g_list_prepend (*list, widget);
5013           
5014           gtk_widget_set_hexpand (widget, TRUE);
5015           gtk_widget_set_vexpand (widget, TRUE);
5016
5017           gtk_grid_attach (GTK_GRID (grid), widget, i, j, 1, 1);
5018         }
5019     }
5020
5021   *list = g_list_reverse (*list);
5022   
5023   return grid;
5024 }
5025
5026 static void
5027 create_focus (GtkWidget *widget)
5028 {
5029   static GtkWidget *window = NULL;
5030   
5031   if (!window)
5032     {
5033       GtkWidget *content_area;
5034       GtkWidget *table;
5035       GtkWidget *frame;
5036       GList *list = NULL;
5037       
5038       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
5039                                             NULL, 0,
5040                                             GTK_STOCK_CLOSE,
5041                                             GTK_RESPONSE_NONE,
5042                                             NULL);
5043
5044       gtk_window_set_screen (GTK_WINDOW (window),
5045                              gtk_widget_get_screen (widget));
5046
5047       g_signal_connect (window, "destroy",
5048                         G_CALLBACK (gtk_widget_destroyed),
5049                         &window);
5050
5051       g_signal_connect (window, "response",
5052                         G_CALLBACK (gtk_widget_destroy),
5053                         NULL);
5054
5055       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5056       
5057       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
5058
5059       frame = gtk_frame_new ("Weird tab focus chain");
5060
5061       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5062       
5063       table = make_focus_table (&list);
5064
5065       gtk_container_add (GTK_CONTAINER (frame), table);
5066
5067       gtk_container_set_focus_chain (GTK_CONTAINER (table),
5068                                      list);
5069
5070       g_list_free (list);
5071       
5072       frame = gtk_frame_new ("Default tab focus chain");
5073
5074       gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5075
5076       list = NULL;
5077       table = make_focus_table (&list);
5078
5079       g_list_free (list);
5080       
5081       gtk_container_add (GTK_CONTAINER (frame), table);      
5082     }
5083   
5084   if (!gtk_widget_get_visible (window))
5085     gtk_widget_show_all (window);
5086   else
5087     gtk_widget_destroy (window);
5088 }
5089
5090 /*
5091  * GtkFontSelection
5092  */
5093
5094 void
5095 create_font_selection (GtkWidget *widget)
5096 {
5097   static GtkWidget *window = NULL;
5098
5099   if (!window)
5100     {
5101       GtkWidget *picker;
5102       GtkWidget *hbox;
5103       GtkWidget *label;
5104       
5105       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5106       gtk_window_set_screen (GTK_WINDOW (window),
5107                              gtk_widget_get_screen (widget));
5108
5109       g_signal_connect (window, "destroy",
5110                         G_CALLBACK (gtk_widget_destroyed),
5111                         &window);
5112
5113       gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
5114       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5115
5116       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
5117       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5118       gtk_container_add (GTK_CONTAINER (window), hbox);
5119       
5120       label = gtk_label_new ("Pick a font");
5121       gtk_container_add (GTK_CONTAINER (hbox), label);
5122
5123       picker = gtk_font_button_new ();
5124       gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
5125       gtk_container_add (GTK_CONTAINER (hbox), picker);
5126     }
5127   
5128   if (!gtk_widget_get_visible (window))
5129     gtk_widget_show_all (window);
5130   else
5131     gtk_widget_destroy (window);
5132 }
5133
5134 /*
5135  * GtkDialog
5136  */
5137
5138 static GtkWidget *dialog_window = NULL;
5139
5140 static void
5141 label_toggle (GtkWidget  *widget,
5142               GtkWidget **label)
5143 {
5144   if (!(*label))
5145     {
5146       *label = gtk_label_new ("Dialog Test");
5147       g_signal_connect (*label,
5148                         "destroy",
5149                         G_CALLBACK (gtk_widget_destroyed),
5150                         label);
5151       g_object_set (*label, "margin", 10, NULL);
5152       gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog_window))),
5153                           *label, TRUE, TRUE, 0);
5154       gtk_widget_show (*label);
5155     }
5156   else
5157     gtk_widget_destroy (*label);
5158 }
5159
5160 static void
5161 create_dialog (GtkWidget *widget)
5162 {
5163   static GtkWidget *label;
5164   GtkWidget *action_area;
5165   GtkWidget *button;
5166
5167   if (!dialog_window)
5168     {
5169       /* This is a terrible example; it's much simpler to create
5170        * dialogs than this. Don't use testgtk for example code,
5171        * use gtk-demo ;-)
5172        */
5173       
5174       dialog_window = gtk_dialog_new ();
5175       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5176                              gtk_widget_get_screen (widget));
5177
5178       g_signal_connect (dialog_window, "destroy",
5179                         G_CALLBACK (gtk_widget_destroyed),
5180                         &dialog_window);
5181
5182       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5183
5184       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5185       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5186
5187       button = gtk_button_new_with_label ("OK");
5188       gtk_widget_set_can_default (button, TRUE);
5189       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5190       gtk_widget_grab_default (button);
5191       gtk_widget_show (button);
5192
5193       button = gtk_button_new_with_label ("Toggle");
5194       g_signal_connect (button, "clicked",
5195                         G_CALLBACK (label_toggle),
5196                         &label);
5197       gtk_widget_set_can_default (button, TRUE);
5198       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5199       gtk_widget_show (button);
5200
5201       label = NULL;
5202     }
5203
5204   if (!gtk_widget_get_visible (dialog_window))
5205     gtk_widget_show (dialog_window);
5206   else
5207     gtk_widget_destroy (dialog_window);
5208 }
5209
5210 /* Display & Screen test 
5211  */
5212
5213 typedef struct
5214 {
5215   GtkWidget *combo;
5216   GtkWidget *entry;
5217   GtkWidget *radio_dpy;
5218   GtkWidget *toplevel;
5219   GtkWidget *dialog_window;
5220 } ScreenDisplaySelection;
5221
5222 static void
5223 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
5224 {
5225   const gchar *display_name;
5226   GdkDisplay *display = gtk_widget_get_display (widget);
5227   GtkWidget *dialog;
5228   GdkScreen *new_screen = NULL;
5229   GdkScreen *current_screen = gtk_widget_get_screen (widget);
5230   
5231   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
5232     {
5233       display_name = gtk_entry_get_text (GTK_ENTRY (data->entry));
5234       display = gdk_display_open (display_name);
5235       
5236       if (!display)
5237         {
5238           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
5239                                            GTK_DIALOG_DESTROY_WITH_PARENT,
5240                                            GTK_MESSAGE_ERROR,
5241                                            GTK_BUTTONS_OK,
5242                                            "The display :\n%s\ncannot be opened",
5243                                            display_name);
5244           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
5245           gtk_widget_show (dialog);
5246           g_signal_connect (dialog, "response",
5247                             G_CALLBACK (gtk_widget_destroy),
5248                             NULL);
5249         }
5250       else
5251         {
5252           GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
5253           gint i = 0;
5254           GtkTreeIter iter;
5255           gboolean found = FALSE;
5256           while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
5257             {
5258               gchar *name;
5259               gtk_tree_model_get (model, &iter, 0, &name, -1);
5260               found = !g_ascii_strcasecmp (display_name, name);
5261               g_free (name);
5262
5263               if (found)
5264                 break;
5265             }
5266           if (!found)
5267             gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (data->combo), display_name);
5268           new_screen = gdk_display_get_default_screen (display);
5269         }
5270     }
5271   else
5272     {
5273       gint number_of_screens = gdk_display_get_n_screens (display);
5274       gint screen_num = gdk_screen_get_number (current_screen);
5275       if ((screen_num +1) < number_of_screens)
5276         new_screen = gdk_display_get_screen (display, screen_num + 1);
5277       else
5278         new_screen = gdk_display_get_screen (display, 0);
5279     }
5280   
5281   if (new_screen) 
5282     {
5283       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
5284       gtk_widget_destroy (data->dialog_window);
5285     }
5286 }
5287
5288 void
5289 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
5290 {
5291   gtk_widget_destroy (data);
5292 }
5293
5294 void
5295 create_display_screen (GtkWidget *widget)
5296 {
5297   GtkWidget *grid, *frame, *window, *combo_dpy, *vbox;
5298   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
5299   GtkWidget *bbox;
5300   ScreenDisplaySelection *scr_dpy_data;
5301   GdkScreen *screen = gtk_widget_get_screen (widget);
5302   GdkDisplay *display = gdk_screen_get_display (screen);
5303
5304   window = g_object_new (gtk_window_get_type (),
5305                          "screen", screen,
5306                          "type", GTK_WINDOW_TOPLEVEL,
5307                          "title", "Screen or Display selection",
5308                          "border_width",
5309                          10, NULL);
5310   g_signal_connect (window, "destroy", 
5311                     G_CALLBACK (gtk_widget_destroy), NULL);
5312
5313   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
5314   gtk_container_add (GTK_CONTAINER (window), vbox);
5315   
5316   frame = gtk_frame_new ("Select screen or display");
5317   gtk_container_add (GTK_CONTAINER (vbox), frame);
5318   
5319   grid = gtk_grid_new ();
5320   gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
5321   gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
5322
5323   gtk_container_add (GTK_CONTAINER (frame), grid);
5324
5325   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
5326   if (gdk_display_get_n_screens(display) > 1)
5327     radio_scr = gtk_radio_button_new_with_label 
5328     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
5329   else
5330     {    
5331       radio_scr = gtk_radio_button_new_with_label 
5332         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
5333          "only one screen on the current display");
5334       gtk_widget_set_sensitive (radio_scr, FALSE);
5335     }
5336   combo_dpy = gtk_combo_box_text_new_with_entry ();
5337   gtk_widget_set_hexpand (combo_dpy, TRUE);
5338   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_dpy), "diabolo:0.0");
5339   gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_dpy))),
5340                       "<hostname>:<X Server Num>.<Screen Num>");
5341
5342   gtk_grid_attach (GTK_GRID (grid), radio_dpy, 0, 0, 1, 1);
5343   gtk_grid_attach (GTK_GRID (grid), radio_scr, 0, 1, 1, 1);
5344   gtk_grid_attach (GTK_GRID (grid), combo_dpy, 1, 0, 1, 1);
5345
5346   bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
5347   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
5348   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
5349   
5350   gtk_container_add (GTK_CONTAINER (vbox), bbox);
5351
5352   gtk_container_add (GTK_CONTAINER (bbox), applyb);
5353   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
5354
5355   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
5356
5357   scr_dpy_data->entry = gtk_bin_get_child (GTK_BIN (combo_dpy));
5358   scr_dpy_data->radio_dpy = radio_dpy;
5359   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
5360   scr_dpy_data->dialog_window = window;
5361
5362   g_signal_connect (cancelb, "clicked", 
5363                     G_CALLBACK (screen_display_destroy_diag), window);
5364   g_signal_connect (applyb, "clicked", 
5365                     G_CALLBACK (screen_display_check), scr_dpy_data);
5366   gtk_widget_show_all (window);
5367 }
5368
5369 /* Event Watcher
5370  */
5371 static gulong event_watcher_enter_id = 0;
5372 static gulong event_watcher_leave_id = 0;
5373
5374 static gboolean
5375 event_watcher (GSignalInvocationHint *ihint,
5376                guint                  n_param_values,
5377                const GValue          *param_values,
5378                gpointer               data)
5379 {
5380   g_print ("Watch: \"%s\" emitted for %s\n",
5381            g_signal_name (ihint->signal_id),
5382            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
5383
5384   return TRUE;
5385 }
5386
5387 static void
5388 event_watcher_down (void)
5389 {
5390   if (event_watcher_enter_id)
5391     {
5392       guint signal_id;
5393
5394       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5395       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5396       event_watcher_enter_id = 0;
5397       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5398       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5399       event_watcher_leave_id = 0;
5400     }
5401 }
5402
5403 static void
5404 event_watcher_toggle (void)
5405 {
5406   if (event_watcher_enter_id)
5407     event_watcher_down ();
5408   else
5409     {
5410       guint signal_id;
5411
5412       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5413       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5414       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5415       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5416     }
5417 }
5418
5419 static void
5420 create_event_watcher (GtkWidget *widget)
5421 {
5422   GtkWidget *action_area, *content_area;
5423   GtkWidget *button;
5424
5425   if (!dialog_window)
5426     {
5427       dialog_window = gtk_dialog_new ();
5428       gtk_window_set_screen (GTK_WINDOW (dialog_window),
5429                              gtk_widget_get_screen (widget));
5430
5431       g_signal_connect (dialog_window, "destroy",
5432                         G_CALLBACK (gtk_widget_destroyed),
5433                         &dialog_window);
5434       g_signal_connect (dialog_window, "destroy",
5435                         G_CALLBACK (event_watcher_down),
5436                         NULL);
5437
5438       content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5439       action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog_window));
5440
5441       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5442       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5443       gtk_widget_set_size_request (dialog_window, 200, 110);
5444
5445       button = gtk_toggle_button_new_with_label ("Activate Watch");
5446       g_signal_connect (button, "clicked",
5447                         G_CALLBACK (event_watcher_toggle),
5448                         NULL);
5449       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5450       gtk_box_pack_start (GTK_BOX (content_area), button, TRUE, TRUE, 0);
5451       gtk_widget_show (button);
5452
5453       button = gtk_button_new_with_label ("Close");
5454       g_signal_connect_swapped (button, "clicked",
5455                                 G_CALLBACK (gtk_widget_destroy),
5456                                 dialog_window);
5457       gtk_widget_set_can_default (button, TRUE);
5458       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
5459       gtk_widget_grab_default (button);
5460       gtk_widget_show (button);
5461     }
5462
5463   if (!gtk_widget_get_visible (dialog_window))
5464     gtk_widget_show (dialog_window);
5465   else
5466     gtk_widget_destroy (dialog_window);
5467 }
5468
5469 /*
5470  * GtkRange
5471  */
5472
5473 static gchar*
5474 reformat_value (GtkScale *scale,
5475                 gdouble   value)
5476 {
5477   return g_strdup_printf ("-->%0.*g<--",
5478                           gtk_scale_get_digits (scale), value);
5479 }
5480
5481 static void
5482 create_range_controls (GtkWidget *widget)
5483 {
5484   static GtkWidget *window = NULL;
5485   GtkWidget *box1;
5486   GtkWidget *box2;
5487   GtkWidget *button;
5488   GtkWidget *scrollbar;
5489   GtkWidget *scale;
5490   GtkWidget *separator;
5491   GtkAdjustment *adjustment;
5492   GtkWidget *hbox;
5493
5494   if (!window)
5495     {
5496       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5497
5498       gtk_window_set_screen (GTK_WINDOW (window),
5499                              gtk_widget_get_screen (widget));
5500
5501       g_signal_connect (window, "destroy",
5502                         G_CALLBACK (gtk_widget_destroyed),
5503                         &window);
5504
5505       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5506       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5507
5508
5509       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
5510       gtk_container_add (GTK_CONTAINER (window), box1);
5511       gtk_widget_show (box1);
5512
5513
5514       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5515       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5516       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5517       gtk_widget_show (box2);
5518
5519
5520       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5521
5522       scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5523       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
5524       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5525       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5526       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5527       gtk_widget_show (scale);
5528
5529       scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5530       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5531       gtk_widget_show (scrollbar);
5532
5533       scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5534       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5535       g_signal_connect (scale,
5536                         "format_value",
5537                         G_CALLBACK (reformat_value),
5538                         NULL);
5539       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5540       gtk_widget_show (scale);
5541       
5542       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5543
5544       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5545       gtk_widget_set_size_request (scale, -1, 200);
5546       gtk_scale_set_digits (GTK_SCALE (scale), 2);
5547       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5548       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5549       gtk_widget_show (scale);
5550
5551       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5552       gtk_widget_set_size_request (scale, -1, 200);
5553       gtk_scale_set_digits (GTK_SCALE (scale), 2);
5554       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5555       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
5556       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5557       gtk_widget_show (scale);
5558
5559       scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5560       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5561       g_signal_connect (scale,
5562                         "format_value",
5563                         G_CALLBACK (reformat_value),
5564                         NULL);
5565       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5566       gtk_widget_show (scale);
5567
5568       
5569       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
5570       gtk_widget_show (hbox);
5571       
5572       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5573       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5574       gtk_widget_show (separator);
5575
5576
5577       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5578       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5579       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5580       gtk_widget_show (box2);
5581
5582
5583       button = gtk_button_new_with_label ("close");
5584       g_signal_connect_swapped (button, "clicked",
5585                                 G_CALLBACK (gtk_widget_destroy),
5586                                 window);
5587       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5588       gtk_widget_set_can_default (button, TRUE);
5589       gtk_widget_grab_default (button);
5590       gtk_widget_show (button);
5591     }
5592
5593   if (!gtk_widget_get_visible (window))
5594     gtk_widget_show (window);
5595   else
5596     gtk_widget_destroy (window);
5597 }
5598
5599 struct {
5600   GdkColor color;
5601   gchar *name;
5602 } text_colors[] = {
5603  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5604  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5605  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5606  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5607  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
5608  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5609  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5610  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5611 };
5612
5613 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5614
5615 /*
5616  * GtkNotebook
5617  */
5618
5619 static const char * book_open_xpm[] = {
5620 "16 16 4 1",
5621 "       c None s None",
5622 ".      c black",
5623 "X      c #808080",
5624 "o      c white",
5625 "                ",
5626 "  ..            ",
5627 " .Xo.    ...    ",
5628 " .Xoo. ..oo.    ",
5629 " .Xooo.Xooo...  ",
5630 " .Xooo.oooo.X.  ",
5631 " .Xooo.Xooo.X.  ",
5632 " .Xooo.oooo.X.  ",
5633 " .Xooo.Xooo.X.  ",
5634 " .Xooo.oooo.X.  ",
5635 "  .Xoo.Xoo..X.  ",
5636 "   .Xo.o..ooX.  ",
5637 "    .X..XXXXX.  ",
5638 "    ..X.......  ",
5639 "     ..         ",
5640 "                "};
5641
5642 static const char * book_closed_xpm[] = {
5643 "16 16 6 1",
5644 "       c None s None",
5645 ".      c black",
5646 "X      c red",
5647 "o      c yellow",
5648 "O      c #808080",
5649 "#      c white",
5650 "                ",
5651 "       ..       ",
5652 "     ..XX.      ",
5653 "   ..XXXXX.     ",
5654 " ..XXXXXXXX.    ",
5655 ".ooXXXXXXXXX.   ",
5656 "..ooXXXXXXXXX.  ",
5657 ".X.ooXXXXXXXXX. ",
5658 ".XX.ooXXXXXX..  ",
5659 " .XX.ooXXX..#O  ",
5660 "  .XX.oo..##OO. ",
5661 "   .XX..##OO..  ",
5662 "    .X.#OO..    ",
5663 "     ..O..      ",
5664 "      ..        ",
5665 "                "};
5666
5667 GdkPixbuf *book_open;
5668 GdkPixbuf *book_closed;
5669 GtkWidget *sample_notebook;
5670
5671 static void
5672 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
5673 {
5674   GtkWidget *page_widget;
5675   GtkWidget *pixwid;
5676
5677   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
5678
5679   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
5680   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
5681   
5682   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
5683   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
5684 }
5685
5686 static void
5687 page_switch (GtkWidget *widget, gpointer *page, gint page_num)
5688 {
5689   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
5690   gint old_page_num = gtk_notebook_get_current_page (notebook);
5691  
5692   if (page_num == old_page_num)
5693     return;
5694
5695   set_page_image (notebook, page_num, book_open);
5696
5697   if (old_page_num != -1)
5698     set_page_image (notebook, old_page_num, book_closed);
5699 }
5700
5701 static void
5702 tab_fill (GtkToggleButton *button, GtkWidget *child)
5703 {
5704   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
5705                            "tab-fill", gtk_toggle_button_get_active (button),
5706                            NULL);
5707 }
5708
5709 static void
5710 tab_expand (GtkToggleButton *button, GtkWidget *child)
5711 {
5712   gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
5713                            "tab-expand", gtk_toggle_button_get_active (button),
5714                            NULL);
5715 }
5716
5717 static void
5718 create_pages (GtkNotebook *notebook, gint start, gint end)
5719 {
5720   GtkWidget *child = NULL;
5721   GtkWidget *button;
5722   GtkWidget *label;
5723   GtkWidget *hbox;
5724   GtkWidget *vbox;
5725   GtkWidget *label_box;
5726   GtkWidget *menu_box;
5727   GtkWidget *pixwid;
5728   gint i;
5729   char buffer[32];
5730   char accel_buffer[32];
5731
5732   for (i = start; i <= end; i++)
5733     {
5734       sprintf (buffer, "Page %d", i);
5735       sprintf (accel_buffer, "Page _%d", i);
5736
5737       child = gtk_frame_new (buffer);
5738       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
5739
5740       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
5741       gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
5742       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
5743       gtk_container_add (GTK_CONTAINER (child), vbox);
5744
5745       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5746       gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
5747       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
5748
5749       button = gtk_check_button_new_with_label ("Fill Tab");
5750       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5751       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
5752       g_signal_connect (button, "toggled",
5753                         G_CALLBACK (tab_fill), child);
5754
5755       button = gtk_check_button_new_with_label ("Expand Tab");
5756       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5757       g_signal_connect (button, "toggled",
5758                         G_CALLBACK (tab_expand), child);
5759
5760       button = gtk_button_new_with_label ("Hide Page");
5761       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
5762       g_signal_connect_swapped (button, "clicked",
5763                                 G_CALLBACK (gtk_widget_hide),
5764                                 child);
5765
5766       gtk_widget_show_all (child);
5767
5768       label_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5769       pixwid = gtk_image_new_from_pixbuf (book_closed);
5770       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
5771                            
5772       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
5773       gtk_widget_set_margin_left (pixwid, 3);
5774       gtk_widget_set_margin_right (pixwid, 3);
5775       gtk_widget_set_margin_bottom (pixwid, 1);
5776       gtk_widget_set_margin_top (pixwid, 1);
5777       label = gtk_label_new_with_mnemonic (accel_buffer);
5778       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
5779       gtk_widget_show_all (label_box);
5780       
5781                                        
5782       menu_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5783       pixwid = gtk_image_new_from_pixbuf (book_closed);
5784       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
5785       
5786       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
5787       gtk_widget_set_margin_left (pixwid, 3);
5788       gtk_widget_set_margin_right (pixwid, 3);
5789       gtk_widget_set_margin_bottom (pixwid, 1);
5790       gtk_widget_set_margin_top (pixwid, 1);
5791       label = gtk_label_new (buffer);
5792       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
5793       gtk_widget_show_all (menu_box);
5794
5795       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
5796     }
5797 }
5798
5799 static void
5800 rotate_notebook (GtkButton   *button,
5801                  GtkNotebook *notebook)
5802 {
5803   gtk_notebook_set_tab_pos (notebook, (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
5804 }
5805
5806 static void
5807 show_all_pages (GtkButton   *button,
5808                 GtkNotebook *notebook)
5809 {  
5810   gtk_container_foreach (GTK_CONTAINER (notebook),
5811                          (GtkCallback) gtk_widget_show, NULL);
5812 }
5813
5814 static void
5815 notebook_type_changed (GtkWidget *optionmenu,
5816                        gpointer   data)
5817 {
5818   GtkNotebook *notebook;
5819   gint i, c;
5820
5821   enum {
5822     STANDARD,
5823     NOTABS,
5824     BORDERLESS,
5825     SCROLLABLE
5826   };
5827
5828   notebook = GTK_NOTEBOOK (data);
5829
5830   c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
5831
5832   switch (c)
5833     {
5834     case STANDARD:
5835       /* standard notebook */
5836       gtk_notebook_set_show_tabs (notebook, TRUE);
5837       gtk_notebook_set_show_border (notebook, TRUE);
5838       gtk_notebook_set_scrollable (notebook, FALSE);
5839       break;
5840
5841     case NOTABS:
5842       /* notabs notebook */
5843       gtk_notebook_set_show_tabs (notebook, FALSE);
5844       gtk_notebook_set_show_border (notebook, TRUE);
5845       break;
5846
5847     case BORDERLESS:
5848       /* borderless */
5849       gtk_notebook_set_show_tabs (notebook, FALSE);
5850       gtk_notebook_set_show_border (notebook, FALSE);
5851       break;
5852
5853     case SCROLLABLE:  
5854       /* scrollable */
5855       gtk_notebook_set_show_tabs (notebook, TRUE);
5856       gtk_notebook_set_show_border (notebook, TRUE);
5857       gtk_notebook_set_scrollable (notebook, TRUE);
5858       if (gtk_notebook_get_n_pages (notebook) == 5)
5859         create_pages (notebook, 6, 15);
5860
5861       return;
5862       break;
5863     }
5864
5865   if (gtk_notebook_get_n_pages (notebook) == 15)
5866     for (i = 0; i < 10; i++)
5867       gtk_notebook_remove_page (notebook, 5);
5868 }
5869
5870 static void
5871 notebook_popup (GtkToggleButton *button,
5872                 GtkNotebook     *notebook)
5873 {
5874   if (gtk_toggle_button_get_active (button))
5875     gtk_notebook_popup_enable (notebook);
5876   else
5877     gtk_notebook_popup_disable (notebook);
5878 }
5879
5880 static void
5881 create_notebook (GtkWidget *widget)
5882 {
5883   static GtkWidget *window = NULL;
5884   GtkWidget *box1;
5885   GtkWidget *box2;
5886   GtkWidget *button;
5887   GtkWidget *separator;
5888   GtkWidget *omenu;
5889   GtkWidget *label;
5890
5891   static gchar *items[] =
5892   {
5893     "Standard",
5894     "No tabs",
5895     "Borderless",
5896     "Scrollable"
5897   };
5898   
5899   if (!window)
5900     {
5901       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5902       gtk_window_set_screen (GTK_WINDOW (window),
5903                              gtk_widget_get_screen (widget));
5904
5905       g_signal_connect (window, "destroy",
5906                         G_CALLBACK (gtk_widget_destroyed),
5907                         &window);
5908
5909       gtk_window_set_title (GTK_WINDOW (window), "notebook");
5910       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5911
5912       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
5913       gtk_container_add (GTK_CONTAINER (window), box1);
5914
5915       sample_notebook = gtk_notebook_new ();
5916       g_signal_connect (sample_notebook, "switch_page",
5917                         G_CALLBACK (page_switch), NULL);
5918       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
5919       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
5920       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
5921
5922       gtk_widget_realize (sample_notebook);
5923
5924       if (!book_open)
5925         book_open = gdk_pixbuf_new_from_xpm_data (book_open_xpm);
5926                                                   
5927       if (!book_closed)
5928         book_closed = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
5929
5930       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
5931
5932       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5933       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
5934       
5935       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
5936       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5937       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5938
5939       button = gtk_check_button_new_with_label ("popup menu");
5940       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
5941       g_signal_connect (button, "clicked",
5942                         G_CALLBACK (notebook_popup),
5943                         sample_notebook);
5944
5945       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
5946       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5947       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5948
5949       label = gtk_label_new ("Notebook Style :");
5950       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
5951
5952       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
5953                                  notebook_type_changed,
5954                                  sample_notebook);
5955       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
5956
5957       button = gtk_button_new_with_label ("Show all Pages");
5958       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
5959       g_signal_connect (button, "clicked",
5960                         G_CALLBACK (show_all_pages), sample_notebook);
5961
5962       box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
5963       gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
5964       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5965       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5966
5967       button = gtk_button_new_with_label ("prev");
5968       g_signal_connect_swapped (button, "clicked",
5969                                 G_CALLBACK (gtk_notebook_prev_page),
5970                                 sample_notebook);
5971       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5972
5973       button = gtk_button_new_with_label ("next");
5974       g_signal_connect_swapped (button, "clicked",
5975                                 G_CALLBACK (gtk_notebook_next_page),
5976                                 sample_notebook);
5977       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5978
5979       button = gtk_button_new_with_label ("rotate");
5980       g_signal_connect (button, "clicked",
5981                         G_CALLBACK (rotate_notebook), sample_notebook);
5982       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5983
5984       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5985       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
5986
5987       button = gtk_button_new_with_label ("close");
5988       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
5989       g_signal_connect_swapped (button, "clicked",
5990                                 G_CALLBACK (gtk_widget_destroy),
5991                                 window);
5992       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
5993       gtk_widget_set_can_default (button, TRUE);
5994       gtk_widget_grab_default (button);
5995     }
5996
5997   if (!gtk_widget_get_visible (window))
5998     gtk_widget_show_all (window);
5999   else
6000     gtk_widget_destroy (window);
6001 }
6002
6003 /*
6004  * GtkPanes
6005  */
6006
6007 void
6008 toggle_resize (GtkWidget *widget, GtkWidget *child)
6009 {
6010   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6011   GValue value = G_VALUE_INIT;
6012   g_value_init (&value, G_TYPE_BOOLEAN);
6013   gtk_container_child_get_property (container, child, "resize", &value);
6014   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6015   gtk_container_child_set_property (container, child, "resize", &value);
6016 }
6017
6018 void
6019 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6020 {
6021   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6022   GValue value = G_VALUE_INIT;
6023   g_value_init (&value, G_TYPE_BOOLEAN);
6024   gtk_container_child_get_property (container, child, "shrink", &value);
6025   g_value_set_boolean (&value, !g_value_get_boolean (&value));
6026   gtk_container_child_set_property (container, child, "shrink", &value);
6027 }
6028
6029 static void
6030 paned_props_clicked (GtkWidget *button,
6031                      GObject   *paned)
6032 {
6033   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
6034   
6035   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
6036 }
6037
6038 GtkWidget *
6039 create_pane_options (GtkPaned    *paned,
6040                      const gchar *frame_label,
6041                      const gchar *label1,
6042                      const gchar *label2)
6043 {
6044   GtkWidget *child1, *child2;
6045   GtkWidget *frame;
6046   GtkWidget *grid;
6047   GtkWidget *label;
6048   GtkWidget *button;
6049   GtkWidget *check_button;
6050
6051   child1 = gtk_paned_get_child1 (paned);
6052   child2 = gtk_paned_get_child2 (paned);
6053
6054   frame = gtk_frame_new (frame_label);
6055   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6056   
6057   grid = gtk_grid_new ();
6058   gtk_container_add (GTK_CONTAINER (frame), grid);
6059   
6060   label = gtk_label_new (label1);
6061   gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
6062   
6063   check_button = gtk_check_button_new_with_label ("Resize");
6064   gtk_grid_attach (GTK_GRID (grid), check_button, 0, 1, 1, 1);
6065   g_signal_connect (check_button, "toggled",
6066                     G_CALLBACK (toggle_resize),
6067                     child1);
6068
6069   check_button = gtk_check_button_new_with_label ("Shrink");
6070   gtk_grid_attach (GTK_GRID (grid), check_button, 0, 2, 1, 1);
6071   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6072                                TRUE);
6073   g_signal_connect (check_button, "toggled",
6074                     G_CALLBACK (toggle_shrink),
6075                     child1);
6076
6077   label = gtk_label_new (label2);
6078   gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
6079   
6080   check_button = gtk_check_button_new_with_label ("Resize");
6081   gtk_grid_attach (GTK_GRID (grid), check_button, 1, 1, 1, 1);
6082   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6083                                TRUE);
6084   g_signal_connect (check_button, "toggled",
6085                     G_CALLBACK (toggle_resize),
6086                     child2);
6087
6088   check_button = gtk_check_button_new_with_label ("Shrink");
6089   gtk_grid_attach (GTK_GRID (grid), check_button, 1, 2, 1, 1);
6090   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6091                                TRUE);
6092   g_signal_connect (check_button, "toggled",
6093                     G_CALLBACK (toggle_shrink),
6094                     child2);
6095
6096   button = gtk_button_new_with_mnemonic ("_Properties");
6097   gtk_grid_attach (GTK_GRID (grid), button, 0, 3, 2, 1);
6098   g_signal_connect (button, "clicked",
6099                     G_CALLBACK (paned_props_clicked),
6100                     paned);
6101
6102   return frame;
6103 }
6104
6105 void
6106 create_panes (GtkWidget *widget)
6107 {
6108   static GtkWidget *window = NULL;
6109   GtkWidget *frame;
6110   GtkWidget *hpaned;
6111   GtkWidget *vpaned;
6112   GtkWidget *button;
6113   GtkWidget *vbox;
6114
6115   if (!window)
6116     {
6117       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6118
6119       gtk_window_set_screen (GTK_WINDOW (window),
6120                              gtk_widget_get_screen (widget));
6121       
6122       g_signal_connect (window, "destroy",
6123                         G_CALLBACK (gtk_widget_destroyed),
6124                         &window);
6125
6126       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6127       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6128
6129       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6130       gtk_container_add (GTK_CONTAINER (window), vbox);
6131       
6132       vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6133       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6134       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6135
6136       hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6137       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6138
6139       frame = gtk_frame_new (NULL);
6140       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6141       gtk_widget_set_size_request (frame, 60, 60);
6142       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6143       
6144       button = gtk_button_new_with_label ("Hi there");
6145       gtk_container_add (GTK_CONTAINER(frame), button);
6146
6147       frame = gtk_frame_new (NULL);
6148       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6149       gtk_widget_set_size_request (frame, 80, 60);
6150       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6151
6152       frame = gtk_frame_new (NULL);
6153       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6154       gtk_widget_set_size_request (frame, 60, 80);
6155       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6156
6157       /* Now create toggle buttons to control sizing */
6158
6159       gtk_box_pack_start (GTK_BOX (vbox),
6160                           create_pane_options (GTK_PANED (hpaned),
6161                                                "Horizontal",
6162                                                "Left",
6163                                                "Right"),
6164                           FALSE, FALSE, 0);
6165
6166       gtk_box_pack_start (GTK_BOX (vbox),
6167                           create_pane_options (GTK_PANED (vpaned),
6168                                                "Vertical",
6169                                                "Top",
6170                                                "Bottom"),
6171                           FALSE, FALSE, 0);
6172
6173       gtk_widget_show_all (vbox);
6174     }
6175
6176   if (!gtk_widget_get_visible (window))
6177     gtk_widget_show (window);
6178   else
6179     gtk_widget_destroy (window);
6180 }
6181
6182 /*
6183  * Paned keyboard navigation
6184  */
6185
6186 static GtkWidget*
6187 paned_keyboard_window1 (GtkWidget *widget)
6188 {
6189   GtkWidget *window1;
6190   GtkWidget *hpaned1;
6191   GtkWidget *frame1;
6192   GtkWidget *vbox1;
6193   GtkWidget *button7;
6194   GtkWidget *button8;
6195   GtkWidget *button9;
6196   GtkWidget *vpaned1;
6197   GtkWidget *frame2;
6198   GtkWidget *frame5;
6199   GtkWidget *hbox1;
6200   GtkWidget *button5;
6201   GtkWidget *button6;
6202   GtkWidget *frame3;
6203   GtkWidget *frame4;
6204   GtkWidget *grid1;
6205   GtkWidget *button1;
6206   GtkWidget *button2;
6207   GtkWidget *button3;
6208   GtkWidget *button4;
6209
6210   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6211   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
6212   gtk_window_set_screen (GTK_WINDOW (window1), 
6213                          gtk_widget_get_screen (widget));
6214
6215   hpaned1 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6216   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
6217
6218   frame1 = gtk_frame_new (NULL);
6219   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
6220   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
6221
6222   vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6223   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
6224
6225   button7 = gtk_button_new_with_label ("button7");
6226   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
6227
6228   button8 = gtk_button_new_with_label ("button8");
6229   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
6230
6231   button9 = gtk_button_new_with_label ("button9");
6232   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
6233
6234   vpaned1 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6235   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
6236
6237   frame2 = gtk_frame_new (NULL);
6238   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
6239   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
6240
6241   frame5 = gtk_frame_new (NULL);
6242   gtk_container_add (GTK_CONTAINER (frame2), frame5);
6243
6244   hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6245   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
6246
6247   button5 = gtk_button_new_with_label ("button5");
6248   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
6249
6250   button6 = gtk_button_new_with_label ("button6");
6251   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
6252
6253   frame3 = gtk_frame_new (NULL);
6254   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
6255   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
6256
6257   frame4 = gtk_frame_new ("Buttons");
6258   gtk_container_add (GTK_CONTAINER (frame3), frame4);
6259   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
6260
6261   grid1 = gtk_grid_new ();
6262   gtk_container_add (GTK_CONTAINER (frame4), grid1);
6263   gtk_container_set_border_width (GTK_CONTAINER (grid1), 11);
6264
6265   button1 = gtk_button_new_with_label ("button1");
6266   gtk_grid_attach (GTK_GRID (grid1), button1, 0, 0, 1, 1);
6267
6268   button2 = gtk_button_new_with_label ("button2");
6269   gtk_grid_attach (GTK_GRID (grid1), button2, 1, 0, 1, 1);
6270
6271   button3 = gtk_button_new_with_label ("button3");
6272   gtk_grid_attach (GTK_GRID (grid1), button3, 0, 1, 1, 1);
6273
6274   button4 = gtk_button_new_with_label ("button4");
6275   gtk_grid_attach (GTK_GRID (grid1), button4, 1, 1, 1, 1);
6276
6277   return window1;
6278 }
6279
6280 static GtkWidget*
6281 paned_keyboard_window2 (GtkWidget *widget)
6282 {
6283   GtkWidget *window2;
6284   GtkWidget *hpaned2;
6285   GtkWidget *frame6;
6286   GtkWidget *button13;
6287   GtkWidget *hbox2;
6288   GtkWidget *vpaned2;
6289   GtkWidget *frame7;
6290   GtkWidget *button12;
6291   GtkWidget *frame8;
6292   GtkWidget *button11;
6293   GtkWidget *button10;
6294
6295   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6296   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
6297
6298   gtk_window_set_screen (GTK_WINDOW (window2), 
6299                          gtk_widget_get_screen (widget));
6300
6301   hpaned2 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6302   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
6303
6304   frame6 = gtk_frame_new (NULL);
6305   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
6306   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
6307
6308   button13 = gtk_button_new_with_label ("button13");
6309   gtk_container_add (GTK_CONTAINER (frame6), button13);
6310
6311   hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6312   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
6313
6314   vpaned2 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6315   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
6316
6317   frame7 = gtk_frame_new (NULL);
6318   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
6319   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
6320
6321   button12 = gtk_button_new_with_label ("button12");
6322   gtk_container_add (GTK_CONTAINER (frame7), button12);
6323
6324   frame8 = gtk_frame_new (NULL);
6325   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
6326   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
6327
6328   button11 = gtk_button_new_with_label ("button11");
6329   gtk_container_add (GTK_CONTAINER (frame8), button11);
6330
6331   button10 = gtk_button_new_with_label ("button10");
6332   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
6333
6334   return window2;
6335 }
6336
6337 static GtkWidget*
6338 paned_keyboard_window3 (GtkWidget *widget)
6339 {
6340   GtkWidget *window3;
6341   GtkWidget *vbox2;
6342   GtkWidget *label1;
6343   GtkWidget *hpaned3;
6344   GtkWidget *frame9;
6345   GtkWidget *button14;
6346   GtkWidget *hpaned4;
6347   GtkWidget *frame10;
6348   GtkWidget *button15;
6349   GtkWidget *hpaned5;
6350   GtkWidget *frame11;
6351   GtkWidget *button16;
6352   GtkWidget *frame12;
6353   GtkWidget *button17;
6354
6355   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6356   g_object_set_data (G_OBJECT (window3), "window3", window3);
6357   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
6358
6359   gtk_window_set_screen (GTK_WINDOW (window3), 
6360                          gtk_widget_get_screen (widget));
6361   
6362
6363   vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6364   gtk_container_add (GTK_CONTAINER (window3), vbox2);
6365
6366   label1 = gtk_label_new ("Three panes nested inside each other");
6367   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
6368
6369   hpaned3 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6370   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
6371
6372   frame9 = gtk_frame_new (NULL);
6373   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
6374   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
6375
6376   button14 = gtk_button_new_with_label ("button14");
6377   gtk_container_add (GTK_CONTAINER (frame9), button14);
6378
6379   hpaned4 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6380   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
6381
6382   frame10 = gtk_frame_new (NULL);
6383   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
6384   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
6385
6386   button15 = gtk_button_new_with_label ("button15");
6387   gtk_container_add (GTK_CONTAINER (frame10), button15);
6388
6389   hpaned5 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6390   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
6391
6392   frame11 = gtk_frame_new (NULL);
6393   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
6394   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
6395
6396   button16 = gtk_button_new_with_label ("button16");
6397   gtk_container_add (GTK_CONTAINER (frame11), button16);
6398
6399   frame12 = gtk_frame_new (NULL);
6400   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
6401   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
6402
6403   button17 = gtk_button_new_with_label ("button17");
6404   gtk_container_add (GTK_CONTAINER (frame12), button17);
6405
6406   return window3;
6407 }
6408
6409 static GtkWidget*
6410 paned_keyboard_window4 (GtkWidget *widget)
6411 {
6412   GtkWidget *window4;
6413   GtkWidget *vbox3;
6414   GtkWidget *label2;
6415   GtkWidget *hpaned6;
6416   GtkWidget *vpaned3;
6417   GtkWidget *button19;
6418   GtkWidget *button18;
6419   GtkWidget *hbox3;
6420   GtkWidget *vpaned4;
6421   GtkWidget *button21;
6422   GtkWidget *button20;
6423   GtkWidget *vpaned5;
6424   GtkWidget *button23;
6425   GtkWidget *button22;
6426   GtkWidget *vpaned6;
6427   GtkWidget *button25;
6428   GtkWidget *button24;
6429
6430   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6431   g_object_set_data (G_OBJECT (window4), "window4", window4);
6432   gtk_window_set_title (GTK_WINDOW (window4), "window4");
6433
6434   gtk_window_set_screen (GTK_WINDOW (window4), 
6435                          gtk_widget_get_screen (widget));
6436
6437   vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6438   gtk_container_add (GTK_CONTAINER (window4), vbox3);
6439
6440   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
6441   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
6442   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
6443
6444   hpaned6 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6445   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
6446
6447   vpaned3 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6448   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
6449
6450   button19 = gtk_button_new_with_label ("button19");
6451   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
6452
6453   button18 = gtk_button_new_with_label ("button18");
6454   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
6455
6456   hbox3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6457   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
6458
6459   vpaned4 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6460   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
6461
6462   button21 = gtk_button_new_with_label ("button21");
6463   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
6464
6465   button20 = gtk_button_new_with_label ("button20");
6466   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
6467
6468   vpaned5 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6469   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
6470
6471   button23 = gtk_button_new_with_label ("button23");
6472   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
6473
6474   button22 = gtk_button_new_with_label ("button22");
6475   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
6476
6477   vpaned6 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6478   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
6479
6480   button25 = gtk_button_new_with_label ("button25");
6481   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
6482
6483   button24 = gtk_button_new_with_label ("button24");
6484   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
6485
6486   return window4;
6487 }
6488
6489 static void
6490 create_paned_keyboard_navigation (GtkWidget *widget)
6491 {
6492   static GtkWidget *window1 = NULL;
6493   static GtkWidget *window2 = NULL;
6494   static GtkWidget *window3 = NULL;
6495   static GtkWidget *window4 = NULL;
6496
6497   if (window1 && 
6498      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
6499     {
6500       gtk_widget_destroy (window1);
6501       gtk_widget_destroy (window2);
6502       gtk_widget_destroy (window3);
6503       gtk_widget_destroy (window4);
6504     }
6505   
6506   if (!window1)
6507     {
6508       window1 = paned_keyboard_window1 (widget);
6509       g_signal_connect (window1, "destroy",
6510                         G_CALLBACK (gtk_widget_destroyed),
6511                         &window1);
6512     }
6513
6514   if (!window2)
6515     {
6516       window2 = paned_keyboard_window2 (widget);
6517       g_signal_connect (window2, "destroy",
6518                         G_CALLBACK (gtk_widget_destroyed),
6519                         &window2);
6520     }
6521
6522   if (!window3)
6523     {
6524       window3 = paned_keyboard_window3 (widget);
6525       g_signal_connect (window3, "destroy",
6526                         G_CALLBACK (gtk_widget_destroyed),
6527                         &window3);
6528     }
6529
6530   if (!window4)
6531     {
6532       window4 = paned_keyboard_window4 (widget);
6533       g_signal_connect (window4, "destroy",
6534                         G_CALLBACK (gtk_widget_destroyed),
6535                         &window4);
6536     }
6537
6538   if (gtk_widget_get_visible (window1))
6539     gtk_widget_destroy (GTK_WIDGET (window1));
6540   else
6541     gtk_widget_show_all (GTK_WIDGET (window1));
6542
6543   if (gtk_widget_get_visible (window2))
6544     gtk_widget_destroy (GTK_WIDGET (window2));
6545   else
6546     gtk_widget_show_all (GTK_WIDGET (window2));
6547
6548   if (gtk_widget_get_visible (window3))
6549     gtk_widget_destroy (GTK_WIDGET (window3));
6550   else
6551     gtk_widget_show_all (GTK_WIDGET (window3));
6552
6553   if (gtk_widget_get_visible (window4))
6554     gtk_widget_destroy (GTK_WIDGET (window4));
6555   else
6556     gtk_widget_show_all (GTK_WIDGET (window4));
6557 }
6558
6559
6560 /*
6561  * Shaped Windows
6562  */
6563
6564 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6565
6566 static void
6567 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6568 {
6569   CursorOffset *p;
6570
6571   /* ignore double and triple click */
6572   if (event->type != GDK_BUTTON_PRESS)
6573     return;
6574
6575   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6576   p->x = (int) event->x;
6577   p->y = (int) event->y;
6578
6579   gtk_grab_add (widget);
6580   gdk_device_grab (gdk_event_get_device ((GdkEvent*)event),
6581                    gtk_widget_get_window (widget),
6582                    GDK_OWNERSHIP_NONE,
6583                    TRUE,
6584                    GDK_BUTTON_RELEASE_MASK |
6585                    GDK_BUTTON_MOTION_MASK |
6586                    GDK_POINTER_MOTION_HINT_MASK,
6587                    NULL,
6588                    event->time);
6589 }
6590
6591 static void
6592 shape_released (GtkWidget      *widget,
6593                 GdkEventButton *event)
6594 {
6595   gtk_grab_remove (widget);
6596   gdk_device_ungrab (gdk_event_get_device ((GdkEvent*)event), event->time);
6597 }
6598
6599 static void
6600 shape_motion (GtkWidget      *widget,
6601               GdkEventMotion *event)
6602 {
6603   gint xp, yp;
6604   CursorOffset * p;
6605
6606   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6607
6608   /*
6609    * Can't use event->x / event->y here 
6610    * because I need absolute coordinates.
6611    */
6612   gdk_window_get_device_position (gdk_screen_get_root_window (gtk_widget_get_screen (widget)),
6613                                   gdk_event_get_device ((GdkEvent *) event),
6614                                   &xp, &yp, NULL);
6615   gtk_window_move (GTK_WINDOW (widget), xp  - p->x, yp  - p->y);
6616 }
6617
6618 GtkWidget *
6619 shape_create_icon (GdkScreen *screen,
6620                    char      *xpm_file,
6621                    gint       x,
6622                    gint       y,
6623                    gint       px,
6624                    gint       py,
6625                    gint       window_type)
6626 {
6627   GtkWidget *window;
6628   GtkWidget *image;
6629   GtkWidget *fixed;
6630   CursorOffset* icon_pos;
6631   cairo_surface_t *mask;
6632   cairo_region_t *mask_region;
6633   GdkPixbuf *pixbuf;
6634   cairo_t *cr;
6635
6636   /*
6637    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
6638    */
6639   window = gtk_window_new (window_type);
6640   gtk_window_set_screen (GTK_WINDOW (window), screen);
6641   
6642   fixed = gtk_fixed_new ();
6643   gtk_widget_set_size_request (fixed, 100, 100);
6644   gtk_container_add (GTK_CONTAINER (window), fixed);
6645   gtk_widget_show (fixed);
6646   
6647   gtk_widget_set_events (window, 
6648                          gtk_widget_get_events (window) |
6649                          GDK_BUTTON_MOTION_MASK |
6650                          GDK_POINTER_MOTION_HINT_MASK |
6651                          GDK_BUTTON_PRESS_MASK);
6652
6653   gtk_widget_realize (window);
6654
6655   pixbuf = gdk_pixbuf_new_from_file (xpm_file, NULL);
6656   g_assert (pixbuf); /* FIXME: error handling */
6657
6658   mask = cairo_image_surface_create (CAIRO_FORMAT_A1,
6659                                      gdk_pixbuf_get_width (pixbuf),
6660                                      gdk_pixbuf_get_height (pixbuf));
6661   cr = cairo_create (mask);
6662   gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
6663   cairo_paint (cr);
6664   cairo_destroy (cr);
6665
6666   mask_region = gdk_cairo_region_create_from_surface (mask);
6667                                                   
6668   cairo_region_translate (mask_region, px, py);
6669
6670   image = gtk_image_new_from_pixbuf (pixbuf);
6671   gtk_fixed_put (GTK_FIXED (fixed), image, px,py);
6672   gtk_widget_show (image);
6673   
6674   gtk_widget_shape_combine_region (window, mask_region);
6675   
6676   cairo_region_destroy (mask_region);
6677   cairo_surface_destroy (mask);
6678   g_object_unref (pixbuf);
6679
6680   g_signal_connect (window, "button_press_event",
6681                     G_CALLBACK (shape_pressed), NULL);
6682   g_signal_connect (window, "button_release_event",
6683                     G_CALLBACK (shape_released), NULL);
6684   g_signal_connect (window, "motion_notify_event",
6685                     G_CALLBACK (shape_motion), NULL);
6686
6687   icon_pos = g_new (CursorOffset, 1);
6688   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
6689
6690   gtk_window_move (GTK_WINDOW (window), x, y);
6691   gtk_widget_show (window);
6692   
6693   return window;
6694 }
6695
6696 void 
6697 create_shapes (GtkWidget *widget)
6698 {
6699   /* Variables used by the Drag/Drop and Shape Window demos */
6700   static GtkWidget *modeller = NULL;
6701   static GtkWidget *sheets = NULL;
6702   static GtkWidget *rings = NULL;
6703   static GtkWidget *with_region = NULL;
6704   GdkScreen *screen = gtk_widget_get_screen (widget);
6705   
6706   if (!(file_exists ("Modeller.xpm") &&
6707         file_exists ("FilesQueue.xpm") &&
6708         file_exists ("3DRings.xpm")))
6709     return;
6710   
6711
6712   if (!modeller)
6713     {
6714       modeller = shape_create_icon (screen, "Modeller.xpm",
6715                                     440, 140, 0,0, GTK_WINDOW_POPUP);
6716
6717       g_signal_connect (modeller, "destroy",
6718                         G_CALLBACK (gtk_widget_destroyed),
6719                         &modeller);
6720     }
6721   else
6722     gtk_widget_destroy (modeller);
6723
6724   if (!sheets)
6725     {
6726       sheets = shape_create_icon (screen, "FilesQueue.xpm",
6727                                   580, 170, 0,0, GTK_WINDOW_POPUP);
6728
6729       g_signal_connect (sheets, "destroy",
6730                         G_CALLBACK (gtk_widget_destroyed),
6731                         &sheets);
6732
6733     }
6734   else
6735     gtk_widget_destroy (sheets);
6736
6737   if (!rings)
6738     {
6739       rings = shape_create_icon (screen, "3DRings.xpm",
6740                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
6741
6742       g_signal_connect (rings, "destroy",
6743                         G_CALLBACK (gtk_widget_destroyed),
6744                         &rings);
6745     }
6746   else
6747     gtk_widget_destroy (rings);
6748
6749   if (!with_region)
6750     {
6751       cairo_region_t *region;
6752       gint x, y;
6753       
6754       with_region = shape_create_icon (screen, "3DRings.xpm",
6755                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
6756
6757       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
6758       
6759       g_signal_connect (with_region, "destroy",
6760                         G_CALLBACK (gtk_widget_destroyed),
6761                         &with_region);
6762
6763       /* reset shape from mask to a region */
6764       x = 0;
6765       y = 0;
6766       region = cairo_region_create ();
6767
6768       while (x < 460)
6769         {
6770           while (y < 270)
6771             {
6772               GdkRectangle rect;
6773               rect.x = x;
6774               rect.y = y;
6775               rect.width = 10;
6776               rect.height = 10;
6777
6778               cairo_region_union_rectangle (region, &rect);
6779               
6780               y += 20;
6781             }
6782           y = 0;
6783           x += 20;
6784         }
6785
6786       gdk_window_shape_combine_region (gtk_widget_get_window (with_region),
6787                                        region,
6788                                        0, 0);
6789     }
6790   else
6791     gtk_widget_destroy (with_region);
6792 }
6793
6794 /*
6795  * WM Hints demo
6796  */
6797
6798 void
6799 create_wmhints (GtkWidget *widget)
6800 {
6801   static GtkWidget *window = NULL;
6802   GtkWidget *label;
6803   GtkWidget *separator;
6804   GtkWidget *button;
6805   GtkWidget *box1;
6806   GtkWidget *box2;
6807   GdkWindow *gdk_window;
6808   GdkPixbuf *pixbuf;
6809   GList *list;
6810
6811   if (!window)
6812     {
6813       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6814
6815       gtk_window_set_screen (GTK_WINDOW (window),
6816                              gtk_widget_get_screen (widget));
6817       
6818       g_signal_connect (window, "destroy",
6819                         G_CALLBACK (gtk_widget_destroyed),
6820                         &window);
6821
6822       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
6823       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6824
6825       gtk_widget_realize (window);
6826
6827       gdk_window = gtk_widget_get_window (window);
6828
6829       pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
6830       list = g_list_prepend (NULL, pixbuf);
6831
6832       gdk_window_set_icon_list (gdk_window, list);
6833       
6834       g_list_free (list);
6835       g_object_unref (pixbuf);
6836
6837       gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
6838   
6839       gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL | GDK_DECOR_MENU);
6840       gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
6841       
6842       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6843       gtk_container_add (GTK_CONTAINER (window), box1);
6844       gtk_widget_show (box1);
6845
6846       label = gtk_label_new ("Try iconizing me!");
6847       gtk_widget_set_size_request (label, 150, 50);
6848       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
6849       gtk_widget_show (label);
6850
6851
6852       separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
6853       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6854       gtk_widget_show (separator);
6855
6856
6857       box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
6858       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6859       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6860       gtk_widget_show (box2);
6861
6862
6863       button = gtk_button_new_with_label ("close");
6864
6865       g_signal_connect_swapped (button, "clicked",
6866                                 G_CALLBACK (gtk_widget_destroy),
6867                                 window);
6868
6869       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6870       gtk_widget_set_can_default (button, TRUE);
6871       gtk_widget_grab_default (button);
6872       gtk_widget_show (button);
6873     }
6874
6875   if (!gtk_widget_get_visible (window))
6876     gtk_widget_show (window);
6877   else
6878     gtk_widget_destroy (window);
6879 }
6880
6881
6882 /*
6883  * Window state tracking
6884  */
6885
6886 static gint
6887 window_state_callback (GtkWidget *widget,
6888                        GdkEventWindowState *event,
6889                        gpointer data)
6890 {
6891   GtkWidget *label = data;
6892   gchar *msg;
6893
6894   msg = g_strconcat (gtk_window_get_title (GTK_WINDOW (widget)), ": ",
6895                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
6896                      "withdrawn" : "not withdrawn", ", ",
6897                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
6898                      "iconified" : "not iconified", ", ",
6899                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
6900                      "sticky" : "not sticky", ", ",
6901                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
6902                      "maximized" : "not maximized", ", ",
6903                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
6904                      "fullscreen" : "not fullscreen",
6905                      (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
6906                      "above" : "not above", ", ",
6907                      (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
6908                      "below" : "not below", ", ",
6909                      NULL);
6910   
6911   gtk_label_set_text (GTK_LABEL (label), msg);
6912
6913   g_free (msg);
6914
6915   return FALSE;
6916 }
6917
6918 static GtkWidget*
6919 tracking_label (GtkWidget *window)
6920 {
6921   GtkWidget *label;
6922   GtkWidget *hbox;
6923   GtkWidget *button;
6924
6925   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
6926
6927   g_signal_connect_object (hbox,
6928                            "destroy",
6929                            G_CALLBACK (gtk_widget_destroy),
6930                            window,
6931                            G_CONNECT_SWAPPED);
6932   
6933   label = gtk_label_new ("<no window state events received>");
6934   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
6935   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
6936   
6937   g_signal_connect (window,
6938                     "window_state_event",
6939                     G_CALLBACK (window_state_callback),
6940                     label);
6941
6942   button = gtk_button_new_with_label ("Deiconify");
6943   g_signal_connect_object (button,
6944                            "clicked",
6945                            G_CALLBACK (gtk_window_deiconify),
6946                            window,
6947                            G_CONNECT_SWAPPED);
6948   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6949
6950   button = gtk_button_new_with_label ("Iconify");
6951   g_signal_connect_object (button,
6952                            "clicked",
6953                            G_CALLBACK (gtk_window_iconify),
6954                            window,
6955                            G_CONNECT_SWAPPED);
6956   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6957
6958   button = gtk_button_new_with_label ("Fullscreen");
6959   g_signal_connect_object (button,
6960                            "clicked",
6961                            G_CALLBACK (gtk_window_fullscreen),
6962                            window,
6963                            G_CONNECT_SWAPPED);
6964   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6965
6966   button = gtk_button_new_with_label ("Unfullscreen");
6967   g_signal_connect_object (button,
6968                            "clicked",
6969                            G_CALLBACK (gtk_window_unfullscreen),
6970                            window,
6971                            G_CONNECT_SWAPPED);
6972   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6973   
6974   button = gtk_button_new_with_label ("Present");
6975   g_signal_connect_object (button,
6976                            "clicked",
6977                            G_CALLBACK (gtk_window_present),
6978                            window,
6979                            G_CONNECT_SWAPPED);
6980   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6981
6982   button = gtk_button_new_with_label ("Show");
6983   g_signal_connect_object (button,
6984                            "clicked",
6985                            G_CALLBACK (gtk_widget_show),
6986                            window,
6987                            G_CONNECT_SWAPPED);
6988   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
6989   
6990   gtk_widget_show_all (hbox);
6991   
6992   return hbox;
6993 }
6994
6995 void
6996 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
6997 {
6998   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
6999
7000   gtk_window_set_keep_above (GTK_WINDOW (data),
7001                              gtk_toggle_button_get_active (togglebutton));
7002
7003   if (gtk_toggle_button_get_active (togglebutton))
7004     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7005 }
7006
7007 void
7008 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
7009 {
7010   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7011
7012   gtk_window_set_keep_below (GTK_WINDOW (data),
7013                              gtk_toggle_button_get_active (togglebutton));
7014
7015   if (gtk_toggle_button_get_active (togglebutton))
7016     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7017 }
7018
7019
7020 static GtkWidget*
7021 get_state_controls (GtkWidget *window)
7022 {
7023   GtkWidget *vbox;
7024   GtkWidget *button;
7025   GtkWidget *button_above;
7026   GtkWidget *button_below;
7027
7028   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7029   
7030   button = gtk_button_new_with_label ("Stick");
7031   g_signal_connect_object (button,
7032                            "clicked",
7033                            G_CALLBACK (gtk_window_stick),
7034                            window,
7035                            G_CONNECT_SWAPPED);
7036   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7037
7038   button = gtk_button_new_with_label ("Unstick");
7039   g_signal_connect_object (button,
7040                            "clicked",
7041                            G_CALLBACK (gtk_window_unstick),
7042                            window,
7043                            G_CONNECT_SWAPPED);
7044   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7045   
7046   button = gtk_button_new_with_label ("Maximize");
7047   g_signal_connect_object (button,
7048                            "clicked",
7049                            G_CALLBACK (gtk_window_maximize),
7050                            window,
7051                            G_CONNECT_SWAPPED);
7052   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7053
7054   button = gtk_button_new_with_label ("Unmaximize");
7055   g_signal_connect_object (button,
7056                            "clicked",
7057                            G_CALLBACK (gtk_window_unmaximize),
7058                            window,
7059                            G_CONNECT_SWAPPED);
7060   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7061
7062   button = gtk_button_new_with_label ("Iconify");
7063   g_signal_connect_object (button,
7064                            "clicked",
7065                            G_CALLBACK (gtk_window_iconify),
7066                            window,
7067                            G_CONNECT_SWAPPED);
7068   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7069
7070   button = gtk_button_new_with_label ("Fullscreen");
7071   g_signal_connect_object (button,
7072                            "clicked",
7073                            G_CALLBACK (gtk_window_fullscreen),
7074                            window,
7075                            G_CONNECT_SWAPPED);
7076   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7077
7078   button = gtk_button_new_with_label ("Unfullscreen");
7079   g_signal_connect_object (button,
7080                            "clicked",
7081                            G_CALLBACK (gtk_window_unfullscreen),
7082                            window,
7083                            G_CONNECT_SWAPPED);
7084   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7085
7086   button_above = gtk_toggle_button_new_with_label ("Keep above");
7087   g_signal_connect (button_above,
7088                     "toggled",
7089                     G_CALLBACK (keep_window_above),
7090                     window);
7091   gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
7092
7093   button_below = gtk_toggle_button_new_with_label ("Keep below");
7094   g_signal_connect (button_below,
7095                     "toggled",
7096                     G_CALLBACK (keep_window_below),
7097                     window);
7098   gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
7099
7100   g_object_set_data (G_OBJECT (button_above), "radio", button_below);
7101   g_object_set_data (G_OBJECT (button_below), "radio", button_above);
7102
7103   button = gtk_button_new_with_label ("Hide (withdraw)");
7104   g_signal_connect_object (button,
7105                            "clicked",
7106                            G_CALLBACK (gtk_widget_hide),
7107                            window,
7108                            G_CONNECT_SWAPPED);
7109   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7110   
7111   gtk_widget_show_all (vbox);
7112
7113   return vbox;
7114 }
7115
7116 void
7117 create_window_states (GtkWidget *widget)
7118 {
7119   static GtkWidget *window = NULL;
7120   GtkWidget *label;
7121   GtkWidget *box1;
7122   GtkWidget *iconified;
7123   GtkWidget *normal;
7124   GtkWidget *controls;
7125
7126   if (!window)
7127     {
7128       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7129       gtk_window_set_screen (GTK_WINDOW (window),
7130                              gtk_widget_get_screen (widget));
7131
7132       g_signal_connect (window, "destroy",
7133                         G_CALLBACK (gtk_widget_destroyed),
7134                         &window);
7135
7136       gtk_window_set_title (GTK_WINDOW (window), "Window states");
7137       
7138       box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7139       gtk_container_add (GTK_CONTAINER (window), box1);
7140
7141       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7142
7143       gtk_window_set_screen (GTK_WINDOW (iconified),
7144                              gtk_widget_get_screen (widget));
7145       
7146       g_signal_connect_object (iconified, "destroy",
7147                                G_CALLBACK (gtk_widget_destroy),
7148                                window,
7149                                G_CONNECT_SWAPPED);
7150       gtk_window_iconify (GTK_WINDOW (iconified));
7151       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
7152       controls = get_state_controls (iconified);
7153       gtk_container_add (GTK_CONTAINER (iconified), controls);
7154       
7155       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7156
7157       gtk_window_set_screen (GTK_WINDOW (normal),
7158                              gtk_widget_get_screen (widget));
7159       
7160       g_signal_connect_object (normal, "destroy",
7161                                G_CALLBACK (gtk_widget_destroy),
7162                                window,
7163                                G_CONNECT_SWAPPED);
7164       
7165       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
7166       controls = get_state_controls (normal);
7167       gtk_container_add (GTK_CONTAINER (normal), controls);
7168       
7169       label = tracking_label (iconified);
7170       gtk_container_add (GTK_CONTAINER (box1), label);
7171
7172       label = tracking_label (normal);
7173       gtk_container_add (GTK_CONTAINER (box1), label);
7174
7175       gtk_widget_show_all (iconified);
7176       gtk_widget_show_all (normal);
7177       gtk_widget_show_all (box1);
7178     }
7179
7180   if (!gtk_widget_get_visible (window))
7181     gtk_widget_show (window);
7182   else
7183     gtk_widget_destroy (window);
7184 }
7185
7186 /*
7187  * Window sizing
7188  */
7189
7190 static gint
7191 configure_event_callback (GtkWidget *widget,
7192                           GdkEventConfigure *event,
7193                           gpointer data)
7194 {
7195   GtkWidget *label = data;
7196   gchar *msg;
7197   gint x, y;
7198   
7199   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
7200   
7201   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
7202                          "position: %d, %d",
7203                          event->x, event->y, event->width, event->height,
7204                          x, y);
7205   
7206   gtk_label_set_text (GTK_LABEL (label), msg);
7207
7208   g_free (msg);
7209
7210   return FALSE;
7211 }
7212
7213 static void
7214 get_ints (GtkWidget *window,
7215           gint      *a,
7216           gint      *b)
7217 {
7218   GtkWidget *spin1;
7219   GtkWidget *spin2;
7220
7221   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
7222   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
7223
7224   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
7225   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7226 }
7227
7228 static void
7229 set_size_callback (GtkWidget *widget,
7230                    gpointer   data)
7231 {
7232   gint w, h;
7233   
7234   get_ints (data, &w, &h);
7235
7236   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
7237 }
7238
7239 static void
7240 unset_default_size_callback (GtkWidget *widget,
7241                              gpointer   data)
7242 {
7243   gtk_window_set_default_size (g_object_get_data (data, "target"),
7244                                -1, -1);
7245 }
7246
7247 static void
7248 set_default_size_callback (GtkWidget *widget,
7249                            gpointer   data)
7250 {
7251   gint w, h;
7252   
7253   get_ints (data, &w, &h);
7254
7255   gtk_window_set_default_size (g_object_get_data (data, "target"),
7256                                w, h);
7257 }
7258
7259 static void
7260 unset_size_request_callback (GtkWidget *widget,
7261                              gpointer   data)
7262 {
7263   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7264                                -1, -1);
7265 }
7266
7267 static void
7268 set_size_request_callback (GtkWidget *widget,
7269                            gpointer   data)
7270 {
7271   gint w, h;
7272   
7273   get_ints (data, &w, &h);
7274
7275   gtk_widget_set_size_request (g_object_get_data (data, "target"),
7276                                w, h);
7277 }
7278
7279 static void
7280 set_location_callback (GtkWidget *widget,
7281                        gpointer   data)
7282 {
7283   gint x, y;
7284   
7285   get_ints (data, &x, &y);
7286
7287   gtk_window_move (g_object_get_data (data, "target"), x, y);
7288 }
7289
7290 static void
7291 move_to_position_callback (GtkWidget *widget,
7292                            gpointer   data)
7293 {
7294   gint x, y;
7295   GtkWindow *window;
7296
7297   window = g_object_get_data (data, "target");
7298   
7299   gtk_window_get_position (window, &x, &y);
7300
7301   gtk_window_move (window, x, y);
7302 }
7303
7304 static void
7305 set_geometry_callback (GtkWidget *entry,
7306                        gpointer   data)
7307 {
7308   gchar *text;
7309   GtkWindow *target;
7310
7311   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
7312   
7313   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
7314
7315   if (!gtk_window_parse_geometry (target, text))
7316     g_print ("Bad geometry string '%s'\n", text);
7317
7318   g_free (text);
7319 }
7320
7321 static void
7322 resizable_callback (GtkWidget *widget,
7323                      gpointer   data)
7324 {
7325   g_object_set (g_object_get_data (data, "target"),
7326                 "resizable", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
7327                 NULL);
7328 }
7329
7330 static void
7331 gravity_selected (GtkWidget *widget,
7332                   gpointer   data)
7333 {
7334   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
7335                           gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GDK_GRAVITY_NORTH_WEST);
7336 }
7337
7338 static void
7339 pos_selected (GtkWidget *widget,
7340               gpointer   data)
7341 {
7342   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
7343                            gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GTK_WIN_POS_NONE);
7344 }
7345
7346 static void
7347 move_gravity_window_to_current_position (GtkWidget *widget,
7348                                          gpointer   data)
7349 {
7350   gint x, y;
7351   GtkWindow *window;
7352
7353   window = GTK_WINDOW (data);    
7354   
7355   gtk_window_get_position (window, &x, &y);
7356
7357   gtk_window_move (window, x, y);
7358 }
7359
7360 static void
7361 get_screen_corner (GtkWindow *window,
7362                    gint      *x,
7363                    gint      *y)
7364 {
7365   int w, h;
7366   GdkScreen * screen = gtk_window_get_screen (window);
7367   
7368   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
7369
7370   switch (gtk_window_get_gravity (window))
7371     {
7372     case GDK_GRAVITY_SOUTH_EAST:
7373       *x = gdk_screen_get_width (screen) - w;
7374       *y = gdk_screen_get_height (screen) - h;
7375       break;
7376
7377     case GDK_GRAVITY_NORTH_EAST:
7378       *x = gdk_screen_get_width (screen) - w;
7379       *y = 0;
7380       break;
7381
7382     case GDK_GRAVITY_SOUTH_WEST:
7383       *x = 0;
7384       *y = gdk_screen_get_height (screen) - h;
7385       break;
7386
7387     case GDK_GRAVITY_NORTH_WEST:
7388       *x = 0;
7389       *y = 0;
7390       break;
7391       
7392     case GDK_GRAVITY_SOUTH:
7393       *x = (gdk_screen_get_width (screen) - w) / 2;
7394       *y = gdk_screen_get_height (screen) - h;
7395       break;
7396
7397     case GDK_GRAVITY_NORTH:
7398       *x = (gdk_screen_get_width (screen) - w) / 2;
7399       *y = 0;
7400       break;
7401
7402     case GDK_GRAVITY_WEST:
7403       *x = 0;
7404       *y = (gdk_screen_get_height (screen) - h) / 2;
7405       break;
7406
7407     case GDK_GRAVITY_EAST:
7408       *x = gdk_screen_get_width (screen) - w;
7409       *y = (gdk_screen_get_height (screen) - h) / 2;
7410       break;
7411
7412     case GDK_GRAVITY_CENTER:
7413       *x = (gdk_screen_get_width (screen) - w) / 2;
7414       *y = (gdk_screen_get_height (screen) - h) / 2;
7415       break;
7416
7417     case GDK_GRAVITY_STATIC:
7418       /* pick some random numbers */
7419       *x = 350;
7420       *y = 350;
7421       break;
7422
7423     default:
7424       g_assert_not_reached ();
7425       break;
7426     }
7427 }
7428
7429 static void
7430 move_gravity_window_to_starting_position (GtkWidget *widget,
7431                                           gpointer   data)
7432 {
7433   gint x, y;
7434   GtkWindow *window;
7435
7436   window = GTK_WINDOW (data);    
7437   
7438   get_screen_corner (window,
7439                      &x, &y);
7440   
7441   gtk_window_move (window, x, y);
7442 }
7443
7444 static GtkWidget*
7445 make_gravity_window (GtkWidget   *destroy_with,
7446                      GdkGravity   gravity,
7447                      const gchar *title)
7448 {
7449   GtkWidget *window;
7450   GtkWidget *button;
7451   GtkWidget *vbox;
7452   int x, y;
7453   
7454   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7455
7456   gtk_window_set_screen (GTK_WINDOW (window),
7457                          gtk_widget_get_screen (destroy_with));
7458
7459   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7460   gtk_widget_show (vbox);
7461   
7462   gtk_container_add (GTK_CONTAINER (window), vbox);
7463   gtk_window_set_title (GTK_WINDOW (window), title);
7464   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
7465
7466   g_signal_connect_object (destroy_with,
7467                            "destroy",
7468                            G_CALLBACK (gtk_widget_destroy),
7469                            window,
7470                            G_CONNECT_SWAPPED);
7471
7472   
7473   button = gtk_button_new_with_mnemonic ("_Move to current position");
7474
7475   g_signal_connect (button, "clicked",
7476                     G_CALLBACK (move_gravity_window_to_current_position),
7477                     window);
7478
7479   gtk_container_add (GTK_CONTAINER (vbox), button);
7480   gtk_widget_show (button);
7481
7482   button = gtk_button_new_with_mnemonic ("Move to _starting position");
7483
7484   g_signal_connect (button, "clicked",
7485                     G_CALLBACK (move_gravity_window_to_starting_position),
7486                     window);
7487
7488   gtk_container_add (GTK_CONTAINER (vbox), button);
7489   gtk_widget_show (button);
7490   
7491   /* Pretend this is the result of --geometry.
7492    * DO NOT COPY THIS CODE unless you are setting --geometry results,
7493    * and in that case you probably should just use gtk_window_parse_geometry().
7494    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
7495    * you are parsing --geometry or equivalent.
7496    */
7497   gtk_window_set_geometry_hints (GTK_WINDOW (window),
7498                                  NULL, NULL,
7499                                  GDK_HINT_USER_POS);
7500
7501   gtk_window_set_default_size (GTK_WINDOW (window),
7502                                200, 200);
7503
7504   get_screen_corner (GTK_WINDOW (window), &x, &y);
7505   
7506   gtk_window_move (GTK_WINDOW (window),
7507                    x, y);
7508   
7509   return window;
7510 }
7511
7512 static void
7513 do_gravity_test (GtkWidget *widget,
7514                  gpointer   data)
7515 {
7516   GtkWidget *destroy_with = data;
7517   GtkWidget *window;
7518   
7519   /* We put a window at each gravity point on the screen. */
7520   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
7521                                 "NorthWest");
7522   gtk_widget_show (window);
7523   
7524   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
7525                                 "SouthEast");
7526   gtk_widget_show (window);
7527
7528   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
7529                                 "NorthEast");
7530   gtk_widget_show (window);
7531
7532   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
7533                                 "SouthWest");
7534   gtk_widget_show (window);
7535
7536   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
7537                                 "South");
7538   gtk_widget_show (window);
7539
7540   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
7541                                 "North");
7542   gtk_widget_show (window);
7543
7544   
7545   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
7546                                 "West");
7547   gtk_widget_show (window);
7548
7549     
7550   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
7551                                 "East");
7552   gtk_widget_show (window);
7553
7554   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
7555                                 "Center");
7556   gtk_widget_show (window);
7557
7558   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
7559                                 "Static");
7560   gtk_widget_show (window);
7561 }
7562
7563 static GtkWidget*
7564 window_controls (GtkWidget *window)
7565 {
7566   GtkWidget *control_window;
7567   GtkWidget *label;
7568   GtkWidget *vbox;
7569   GtkWidget *button;
7570   GtkWidget *spin;
7571   GtkAdjustment *adjustment;
7572   GtkWidget *entry;
7573   GtkWidget *om;
7574   gint i;
7575   
7576   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7577
7578   gtk_window_set_screen (GTK_WINDOW (control_window),
7579                          gtk_widget_get_screen (window));
7580
7581   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
7582   
7583   g_object_set_data (G_OBJECT (control_window),
7584                      "target",
7585                      window);
7586   
7587   g_signal_connect_object (control_window,
7588                            "destroy",
7589                            G_CALLBACK (gtk_widget_destroy),
7590                            window,
7591                            G_CONNECT_SWAPPED);
7592
7593   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
7594   
7595   gtk_container_add (GTK_CONTAINER (control_window), vbox);
7596   
7597   label = gtk_label_new ("<no configure events>");
7598   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7599   
7600   g_signal_connect (window,
7601                     "configure_event",
7602                     G_CALLBACK (configure_event_callback),
7603                     label);
7604
7605   adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7606   spin = gtk_spin_button_new (adjustment, 0, 0);
7607
7608   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7609
7610   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
7611
7612   adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7613   spin = gtk_spin_button_new (adjustment, 0, 0);
7614
7615   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7616
7617   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
7618
7619   entry = gtk_entry_new ();
7620   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
7621
7622   g_signal_connect (entry, "changed",
7623                     G_CALLBACK (set_geometry_callback),
7624                     control_window);
7625
7626   button = gtk_button_new_with_label ("Show gravity test windows");
7627   g_signal_connect_swapped (button,
7628                             "clicked",
7629                             G_CALLBACK (do_gravity_test),
7630                             control_window);
7631   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7632
7633   button = gtk_button_new_with_label ("Reshow with initial size");
7634   g_signal_connect_object (button,
7635                            "clicked",
7636                            G_CALLBACK (gtk_window_reshow_with_initial_size),
7637                            window,
7638                            G_CONNECT_SWAPPED);
7639   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7640   
7641   button = gtk_button_new_with_label ("Queue resize");
7642   g_signal_connect_object (button,
7643                            "clicked",
7644                            G_CALLBACK (gtk_widget_queue_resize),
7645                            window,
7646                            G_CONNECT_SWAPPED);
7647   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7648   
7649   button = gtk_button_new_with_label ("Resize");
7650   g_signal_connect (button,
7651                     "clicked",
7652                     G_CALLBACK (set_size_callback),
7653                     control_window);
7654   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7655
7656   button = gtk_button_new_with_label ("Set default size");
7657   g_signal_connect (button,
7658                     "clicked",
7659                     G_CALLBACK (set_default_size_callback),
7660                     control_window);
7661   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7662
7663   button = gtk_button_new_with_label ("Unset default size");
7664   g_signal_connect (button,
7665                     "clicked",
7666                     G_CALLBACK (unset_default_size_callback),
7667                     control_window);
7668   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7669   
7670   button = gtk_button_new_with_label ("Set size request");
7671   g_signal_connect (button,
7672                     "clicked",
7673                     G_CALLBACK (set_size_request_callback),
7674                     control_window);
7675   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7676
7677   button = gtk_button_new_with_label ("Unset size request");
7678   g_signal_connect (button,
7679                     "clicked",
7680                     G_CALLBACK (unset_size_request_callback),
7681                     control_window);
7682   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7683   
7684   button = gtk_button_new_with_label ("Move");
7685   g_signal_connect (button,
7686                     "clicked",
7687                     G_CALLBACK (set_location_callback),
7688                     control_window);
7689   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7690
7691   button = gtk_button_new_with_label ("Move to current position");
7692   g_signal_connect (button,
7693                     "clicked",
7694                     G_CALLBACK (move_to_position_callback),
7695                     control_window);
7696   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7697
7698   button = gtk_check_button_new_with_label ("Allow resize");
7699   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
7700   g_signal_connect (button,
7701                     "toggled",
7702                     G_CALLBACK (resizable_callback),
7703                     control_window);
7704   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7705   
7706   button = gtk_button_new_with_mnemonic ("_Show");
7707   g_signal_connect_object (button,
7708                            "clicked",
7709                            G_CALLBACK (gtk_widget_show),
7710                            window,
7711                            G_CONNECT_SWAPPED);
7712   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7713
7714   button = gtk_button_new_with_mnemonic ("_Hide");
7715   g_signal_connect_object (button,
7716                            "clicked",
7717                            G_CALLBACK (gtk_widget_hide),
7718                            window,
7719                            G_CONNECT_SWAPPED);
7720   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7721
7722   om = gtk_combo_box_text_new ();
7723   i = 0;
7724   while (i < 10)
7725     {
7726       static gchar *names[] = {
7727         "GDK_GRAVITY_NORTH_WEST",
7728         "GDK_GRAVITY_NORTH",
7729         "GDK_GRAVITY_NORTH_EAST",
7730         "GDK_GRAVITY_WEST",
7731         "GDK_GRAVITY_CENTER",
7732         "GDK_GRAVITY_EAST",
7733         "GDK_GRAVITY_SOUTH_WEST",
7734         "GDK_GRAVITY_SOUTH",
7735         "GDK_GRAVITY_SOUTH_EAST",
7736         "GDK_GRAVITY_STATIC",
7737         NULL
7738       };
7739
7740       g_assert (names[i]);
7741       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
7742
7743       ++i;
7744     }
7745   
7746   g_signal_connect (om,
7747                     "changed",
7748                     G_CALLBACK (gravity_selected),
7749                     control_window);
7750
7751   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
7752
7753
7754   om = gtk_combo_box_text_new ();
7755   i = 0;
7756   while (i < 5)
7757     {
7758       static gchar *names[] = {
7759         "GTK_WIN_POS_NONE",
7760         "GTK_WIN_POS_CENTER",
7761         "GTK_WIN_POS_MOUSE",
7762         "GTK_WIN_POS_CENTER_ALWAYS",
7763         "GTK_WIN_POS_CENTER_ON_PARENT",
7764         NULL
7765       };
7766
7767       g_assert (names[i]);
7768       gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
7769
7770       ++i;
7771     }
7772
7773   g_signal_connect (om,
7774                     "changed",
7775                     G_CALLBACK (pos_selected),
7776                     control_window);
7777
7778   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
7779   
7780   gtk_widget_show_all (vbox);
7781   
7782   return control_window;
7783 }
7784
7785 void
7786 create_window_sizing (GtkWidget *widget)
7787 {
7788   static GtkWidget *window = NULL;
7789   static GtkWidget *target_window = NULL;
7790
7791   if (!target_window)
7792     {
7793       GtkWidget *label;
7794       
7795       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7796       gtk_window_set_screen (GTK_WINDOW (target_window),
7797                              gtk_widget_get_screen (widget));
7798       label = gtk_label_new (NULL);
7799       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");
7800       gtk_container_add (GTK_CONTAINER (target_window), label);
7801       gtk_widget_show (label);
7802       
7803       g_signal_connect (target_window, "destroy",
7804                         G_CALLBACK (gtk_widget_destroyed),
7805                         &target_window);
7806
7807       window = window_controls (target_window);
7808       
7809       g_signal_connect (window, "destroy",
7810                         G_CALLBACK (gtk_widget_destroyed),
7811                         &window);
7812       
7813       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
7814     }
7815
7816   /* don't show target window by default, we want to allow testing
7817    * of behavior on first show.
7818    */
7819   
7820   if (!gtk_widget_get_visible (window))
7821     gtk_widget_show (window);
7822   else
7823     gtk_widget_destroy (window);
7824 }
7825
7826 /*
7827  * GtkProgressBar
7828  */
7829
7830 typedef struct _ProgressData {
7831   GtkWidget *window;
7832   GtkWidget *pbar;
7833   GtkWidget *block_spin;
7834   GtkWidget *x_align_spin;
7835   GtkWidget *y_align_spin;
7836   GtkWidget *step_spin;
7837   GtkWidget *act_blocks_spin;
7838   GtkWidget *label;
7839   GtkWidget *omenu1;
7840   GtkWidget *elmenu;
7841   GtkWidget *omenu2;
7842   GtkWidget *entry;
7843   int timer;
7844   gboolean activity;
7845 } ProgressData;
7846
7847 gboolean
7848 progress_timeout (gpointer data)
7849 {
7850   ProgressData *pdata = data;
7851   gdouble new_val;
7852   gchar *text;
7853
7854   if (pdata->activity)
7855     {
7856       gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
7857
7858       text = g_strdup_printf ("%s", "???");
7859     }
7860   else
7861     {
7862       new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
7863       if (new_val > 1.00)
7864         new_val = 0.00;
7865       gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
7866
7867       text = g_strdup_printf ("%.0f%%", 100 * new_val);
7868     }
7869
7870   gtk_label_set_text (GTK_LABEL (pdata->label), text);
7871   g_free (text);
7872
7873   return TRUE;
7874 }
7875
7876 static void
7877 destroy_progress (GtkWidget     *widget,
7878                   ProgressData **pdata)
7879 {
7880   if ((*pdata)->timer)
7881     {
7882       g_source_remove ((*pdata)->timer);
7883       (*pdata)->timer = 0;
7884     }
7885   (*pdata)->window = NULL;
7886   g_free (*pdata);
7887   *pdata = NULL;
7888 }
7889
7890 static void
7891 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
7892 {
7893   ProgressData *pdata;
7894   gint i;
7895
7896   pdata = (ProgressData *) data;
7897
7898   if (!gtk_widget_get_mapped (widget))
7899     return;
7900
7901   i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
7902
7903   if (i == 0 || i == 1)
7904     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_HORIZONTAL);
7905   else
7906     gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_VERTICAL);
7907  
7908   if (i == 1 || i == 2)
7909     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
7910   else
7911     gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
7912 }
7913
7914 static void
7915 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
7916 {
7917   gboolean active;
7918
7919   active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
7920   gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), active);
7921 }
7922
7923 static void
7924 progressbar_toggle_ellipsize (GtkWidget *widget,
7925                               gpointer   data)
7926 {
7927   ProgressData *pdata = data;
7928   if (gtk_widget_is_drawable (widget))
7929     {
7930       gint i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
7931       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
7932     }
7933 }
7934
7935 static void
7936 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
7937 {
7938   pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
7939 }
7940
7941 static void
7942 toggle_running (GtkWidget *widget, ProgressData *pdata)
7943 {
7944   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
7945     {
7946       if (pdata->timer == 0)
7947         pdata->timer = g_timeout_add (100, (GSourceFunc)progress_timeout, pdata);
7948     }
7949   else
7950     {
7951       if (pdata->timer != 0)
7952         {
7953           g_source_remove (pdata->timer);
7954           pdata->timer = 0;
7955         }
7956     }
7957 }
7958
7959 static void
7960 entry_changed (GtkWidget *widget, ProgressData *pdata)
7961 {
7962   gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
7963                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
7964 }
7965
7966 void
7967 create_progress_bar (GtkWidget *widget)
7968 {
7969   GtkWidget *action_area, *content_area;
7970   GtkWidget *button;
7971   GtkWidget *vbox;
7972   GtkWidget *vbox2;
7973   GtkWidget *hbox;
7974   GtkWidget *check;
7975   GtkWidget *frame;
7976   GtkWidget *grid;
7977   GtkWidget *label;
7978   GtkWidget *align;
7979   static ProgressData *pdata = NULL;
7980
7981   static gchar *items1[] =
7982   {
7983     "Left-Right",
7984     "Right-Left",
7985     "Bottom-Top",
7986     "Top-Bottom"
7987   };
7988
7989     static char *ellipsize_items[] = {
7990     "None",     // PANGO_ELLIPSIZE_NONE,
7991     "Start",    // PANGO_ELLIPSIZE_START,
7992     "Middle",   // PANGO_ELLIPSIZE_MIDDLE,
7993     "End",      // PANGO_ELLIPSIZE_END
7994   };
7995   
7996   if (!pdata)
7997     pdata = g_new0 (ProgressData, 1);
7998
7999   if (!pdata->window)
8000     {
8001       pdata->window = gtk_dialog_new ();
8002
8003       gtk_window_set_screen (GTK_WINDOW (pdata->window),
8004                              gtk_widget_get_screen (widget));
8005
8006       gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
8007
8008       g_signal_connect (pdata->window, "destroy",
8009                         G_CALLBACK (destroy_progress),
8010                         &pdata);
8011       pdata->timer = 0;
8012
8013       content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
8014       action_area = gtk_dialog_get_action_area (GTK_DIALOG (pdata->window));
8015
8016       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
8017       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
8018
8019       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8020       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8021       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
8022
8023       frame = gtk_frame_new ("Progress");
8024       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8025
8026       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8027       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8028
8029       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8030       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8031
8032       pdata->pbar = gtk_progress_bar_new ();
8033       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
8034                                       PANGO_ELLIPSIZE_MIDDLE);
8035
8036       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
8037
8038       align = gtk_alignment_new (0.5, 0.5, 0, 0);
8039       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
8040
8041       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
8042       gtk_container_add (GTK_CONTAINER (align), hbox);
8043       label = gtk_label_new ("Label updated by user :"); 
8044       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8045       pdata->label = gtk_label_new ("");
8046       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
8047
8048       frame = gtk_frame_new ("Options");
8049       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8050
8051       vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8052       gtk_container_add (GTK_CONTAINER (frame), vbox2);
8053
8054       grid = gtk_grid_new ();
8055       gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
8056       gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
8057       gtk_box_pack_start (GTK_BOX (vbox2), grid, FALSE, TRUE, 0);
8058
8059       label = gtk_label_new ("Orientation :");
8060       gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
8061       gtk_widget_set_halign (label, GTK_ALIGN_START);
8062       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
8063
8064       pdata->omenu1 = build_option_menu (items1, 4, 0,
8065                                          progressbar_toggle_orientation,
8066                                          pdata);
8067       gtk_grid_attach (GTK_GRID (grid), pdata->omenu1, 1, 0, 1, 1);
8068       
8069       check = gtk_check_button_new_with_label ("Running");
8070       g_signal_connect (check, "toggled",
8071                         G_CALLBACK (toggle_running),
8072                         pdata);
8073       gtk_grid_attach (GTK_GRID (grid), check, 0, 1, 2, 1);
8074       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
8075
8076       check = gtk_check_button_new_with_label ("Show text");
8077       g_signal_connect (check, "clicked",
8078                         G_CALLBACK (toggle_show_text),
8079                         pdata);
8080       gtk_grid_attach (GTK_GRID (grid), check, 0, 2, 1, 1);
8081
8082       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8083       gtk_grid_attach (GTK_GRID (grid), hbox, 1, 2, 1, 1);
8084
8085       label = gtk_label_new ("Text: ");
8086       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8087
8088       pdata->entry = gtk_entry_new ();
8089       gtk_widget_set_hexpand (pdata->entry, TRUE);
8090       g_signal_connect (pdata->entry, "changed",
8091                         G_CALLBACK (entry_changed),
8092                         pdata);
8093       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
8094       gtk_widget_set_size_request (pdata->entry, 100, -1);
8095
8096       label = gtk_label_new ("Ellipsize text :");
8097       gtk_grid_attach (GTK_GRID (grid), label, 0, 10, 1, 1);
8098
8099       gtk_widget_set_halign (label, GTK_ALIGN_START);
8100       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
8101       pdata->elmenu = build_option_menu (ellipsize_items,
8102                                          sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
8103                                          2, // PANGO_ELLIPSIZE_MIDDLE
8104                                          progressbar_toggle_ellipsize,
8105                                          pdata);
8106       gtk_grid_attach (GTK_GRID (grid), pdata->elmenu, 1, 10, 1, 1);
8107
8108       check = gtk_check_button_new_with_label ("Activity mode");
8109       g_signal_connect (check, "clicked",
8110                         G_CALLBACK (toggle_activity_mode), pdata);
8111       gtk_grid_attach (GTK_GRID (grid), check, 0, 15, 1, 1);
8112
8113       button = gtk_button_new_with_label ("close");
8114       g_signal_connect_swapped (button, "clicked",
8115                                 G_CALLBACK (gtk_widget_destroy),
8116                                 pdata->window);
8117       gtk_widget_set_can_default (button, TRUE);
8118       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8119       gtk_widget_grab_default (button);
8120     }
8121
8122   if (!gtk_widget_get_visible (pdata->window))
8123     gtk_widget_show_all (pdata->window);
8124   else
8125     gtk_widget_destroy (pdata->window);
8126 }
8127
8128 /*
8129  * Properties
8130  */
8131
8132 typedef struct {
8133   int x;
8134   int y;
8135   gboolean found;
8136   gboolean first;
8137   GtkWidget *res_widget;
8138 } FindWidgetData;
8139
8140 static void
8141 find_widget (GtkWidget *widget, FindWidgetData *data)
8142 {
8143   GtkAllocation new_allocation;
8144   gint x_offset = 0;
8145   gint y_offset = 0;
8146
8147   gtk_widget_get_allocation (widget, &new_allocation);
8148
8149   if (data->found || !gtk_widget_get_mapped (widget))
8150     return;
8151
8152   /* Note that in the following code, we only count the
8153    * position as being inside a WINDOW widget if it is inside
8154    * widget->window; points that are outside of widget->window
8155    * but within the allocation are not counted. This is consistent
8156    * with the way we highlight drag targets.
8157    */
8158   if (gtk_widget_get_has_window (widget))
8159     {
8160       new_allocation.x = 0;
8161       new_allocation.y = 0;
8162     }
8163
8164   if (gtk_widget_get_parent (widget) && !data->first)
8165     {
8166       GdkWindow *window = gtk_widget_get_window (widget);
8167       while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
8168         {
8169           gint tx, ty, twidth, theight;
8170           
8171           twidth = gdk_window_get_width (window);
8172           theight = gdk_window_get_height (window);
8173
8174           if (new_allocation.x < 0)
8175             {
8176               new_allocation.width += new_allocation.x;
8177               new_allocation.x = 0;
8178             }
8179           if (new_allocation.y < 0)
8180             {
8181               new_allocation.height += new_allocation.y;
8182               new_allocation.y = 0;
8183             }
8184           if (new_allocation.x + new_allocation.width > twidth)
8185             new_allocation.width = twidth - new_allocation.x;
8186           if (new_allocation.y + new_allocation.height > theight)
8187             new_allocation.height = theight - new_allocation.y;
8188
8189           gdk_window_get_position (window, &tx, &ty);
8190           new_allocation.x += tx;
8191           x_offset += tx;
8192           new_allocation.y += ty;
8193           y_offset += ty;
8194
8195           window = gdk_window_get_parent (window);
8196         }
8197     }
8198
8199   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
8200       (data->x < new_allocation.x + new_allocation.width) && 
8201       (data->y < new_allocation.y + new_allocation.height))
8202     {
8203       /* First, check if the drag is in a valid drop site in
8204        * one of our children 
8205        */
8206       if (GTK_IS_CONTAINER (widget))
8207         {
8208           FindWidgetData new_data = *data;
8209           
8210           new_data.x -= x_offset;
8211           new_data.y -= y_offset;
8212           new_data.found = FALSE;
8213           new_data.first = FALSE;
8214           
8215           gtk_container_forall (GTK_CONTAINER (widget),
8216                                 (GtkCallback)find_widget,
8217                                 &new_data);
8218           
8219           data->found = new_data.found;
8220           if (data->found)
8221             data->res_widget = new_data.res_widget;
8222         }
8223
8224       /* If not, and this widget is registered as a drop site, check to
8225        * emit "drag_motion" to check if we are actually in
8226        * a drop site.
8227        */
8228       if (!data->found)
8229         {
8230           data->found = TRUE;
8231           data->res_widget = widget;
8232         }
8233     }
8234 }
8235
8236 static GtkWidget *
8237 find_widget_at_pointer (GdkDevice *device)
8238 {
8239   GtkWidget *widget = NULL;
8240   GdkWindow *pointer_window;
8241   gint x, y;
8242   FindWidgetData data;
8243  
8244  pointer_window = gdk_device_get_window_at_position (device, NULL, NULL);
8245  
8246  if (pointer_window)
8247    {
8248      gpointer widget_ptr;
8249
8250      gdk_window_get_user_data (pointer_window, &widget_ptr);
8251      widget = widget_ptr;
8252    }
8253
8254  if (widget)
8255    {
8256      gdk_window_get_device_position (gtk_widget_get_window (widget),
8257                                      device,
8258                                      &x, &y, NULL);
8259      
8260      data.x = x;
8261      data.y = y;
8262      data.found = FALSE;
8263      data.first = TRUE;
8264
8265      find_widget (widget, &data);
8266      if (data.found)
8267        return data.res_widget;
8268      return widget;
8269    }
8270  return NULL;
8271 }
8272
8273 struct PropertiesData {
8274   GtkWidget **window;
8275   GdkCursor *cursor;
8276   gboolean in_query;
8277   gulong handler;
8278 };
8279
8280 static void
8281 destroy_properties (GtkWidget             *widget,
8282                     struct PropertiesData *data)
8283 {
8284   if (data->window)
8285     {
8286       *data->window = NULL;
8287       data->window = NULL;
8288     }
8289
8290   if (data->cursor)
8291     {
8292       g_object_unref (data->cursor);
8293       data->cursor = NULL;
8294     }
8295
8296   if (data->handler)
8297     {
8298       g_signal_handler_disconnect (widget, data->handler);
8299       data->handler = 0;
8300     }
8301
8302   g_free (data);
8303 }
8304
8305 static gint
8306 property_query_event (GtkWidget             *widget,
8307                       GdkEvent              *event,
8308                       struct PropertiesData *data)
8309 {
8310   GtkWidget *res_widget = NULL;
8311
8312   if (!data->in_query)
8313     return FALSE;
8314
8315   if (event->type == GDK_BUTTON_RELEASE)
8316     {
8317       gtk_grab_remove (widget);
8318       gdk_device_ungrab (gdk_event_get_device (event), GDK_CURRENT_TIME);
8319
8320       res_widget = find_widget_at_pointer (gdk_event_get_device (event));
8321       if (res_widget)
8322         {
8323           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
8324                              gtk_widget_get_screen (widget));
8325           create_prop_editor (G_OBJECT (res_widget), 0);
8326         }
8327
8328       data->in_query = FALSE;
8329     }
8330   return FALSE;
8331 }
8332
8333
8334 static void
8335 query_properties (GtkButton *button,
8336                   struct PropertiesData *data)
8337 {
8338   GtkWidget *widget = GTK_WIDGET (button);
8339   GdkDisplay *display;
8340   GdkDeviceManager *device_manager;
8341   GdkDevice *device;
8342
8343   g_signal_connect (button, "event",
8344                     G_CALLBACK (property_query_event), data);
8345
8346   display = gtk_widget_get_display (widget);
8347
8348   if (!data->cursor)
8349     data->cursor = gdk_cursor_new_for_display (display, GDK_TARGET);
8350
8351   device_manager = gdk_display_get_device_manager (display);
8352   device = gdk_device_manager_get_client_pointer (device_manager);
8353   gdk_device_grab (device,
8354                    gtk_widget_get_window (widget),
8355                    GDK_OWNERSHIP_NONE,
8356                    TRUE,
8357                    GDK_BUTTON_RELEASE_MASK,
8358                    data->cursor,
8359                    GDK_CURRENT_TIME);
8360   gtk_grab_add (widget);
8361
8362   data->in_query = TRUE;
8363 }
8364
8365 static void
8366 create_properties (GtkWidget *widget)
8367 {
8368   static GtkWidget *window = NULL;
8369   GtkWidget *button;
8370   GtkWidget *vbox;
8371   GtkWidget *label;
8372   struct PropertiesData *data;
8373
8374   data = g_new (struct PropertiesData, 1);
8375   data->window = &window;
8376   data->in_query = FALSE;
8377   data->cursor = NULL;
8378   data->handler = 0;
8379
8380   if (!window)
8381     {
8382       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8383
8384       gtk_window_set_screen (GTK_WINDOW (window),
8385                              gtk_widget_get_screen (widget));      
8386
8387       data->handler = g_signal_connect (window, "destroy",
8388                                         G_CALLBACK (destroy_properties),
8389                                         data);
8390
8391       gtk_window_set_title (GTK_WINDOW (window), "test properties");
8392       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8393
8394       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
8395       gtk_container_add (GTK_CONTAINER (window), vbox);
8396             
8397       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
8398       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
8399       
8400       button = gtk_button_new_with_label ("Query properties");
8401       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8402       g_signal_connect (button, "clicked",
8403                         G_CALLBACK (query_properties),
8404                         data);
8405     }
8406
8407   if (!gtk_widget_get_visible (window))
8408     gtk_widget_show_all (window);
8409   else
8410     gtk_widget_destroy (window);
8411   
8412 }
8413
8414 struct SnapshotData {
8415   GtkWidget *toplevel_button;
8416   GtkWidget **window;
8417   GdkCursor *cursor;
8418   gboolean in_query;
8419   gboolean is_toplevel;
8420   gint handler;
8421 };
8422
8423 static void
8424 destroy_snapshot_data (GtkWidget             *widget,
8425                        struct SnapshotData *data)
8426 {
8427   if (*data->window)
8428     *data->window = NULL;
8429   
8430   if (data->cursor)
8431     {
8432       g_object_unref (data->cursor);
8433       data->cursor = NULL;
8434     }
8435
8436   if (data->handler)
8437     {
8438       g_signal_handler_disconnect (widget, data->handler);
8439       data->handler = 0;
8440     }
8441
8442   g_free (data);
8443 }
8444
8445 static gint
8446 snapshot_widget_event (GtkWidget               *widget,
8447                        GdkEvent        *event,
8448                        struct SnapshotData *data)
8449 {
8450   GtkWidget *res_widget = NULL;
8451
8452   if (!data->in_query)
8453     return FALSE;
8454   
8455   if (event->type == GDK_BUTTON_RELEASE)
8456     {
8457       gtk_grab_remove (widget);
8458       gdk_device_ungrab (gdk_event_get_device (event),
8459                          GDK_CURRENT_TIME);
8460       
8461       res_widget = find_widget_at_pointer (gdk_event_get_device (event));
8462       if (data->is_toplevel && res_widget)
8463         res_widget = gtk_widget_get_toplevel (res_widget);
8464       if (res_widget)
8465         {
8466           cairo_surface_t *surface;
8467           GtkWidget *window, *image;
8468           GdkPixbuf *pixbuf;
8469           int width, height;
8470           cairo_t *cr;
8471
8472           width = gtk_widget_get_allocated_width (res_widget);
8473           height = gtk_widget_get_allocated_height (res_widget);
8474
8475           surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
8476
8477           cr = cairo_create (surface);
8478           gtk_widget_draw (res_widget, cr);
8479           cairo_destroy (cr);
8480
8481           pixbuf = gdk_pixbuf_get_from_surface (surface,
8482                                                 0, 0,
8483                                                 width, height);
8484           cairo_surface_destroy (surface);
8485
8486           window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8487           image = gtk_image_new_from_pixbuf (pixbuf);
8488           g_object_unref (pixbuf);
8489
8490           gtk_container_add (GTK_CONTAINER (window), image);
8491           gtk_widget_show_all (window);
8492         }
8493
8494       data->in_query = FALSE;
8495     }
8496   return FALSE;
8497 }
8498
8499
8500 static void
8501 snapshot_widget (GtkButton *button,
8502                  struct SnapshotData *data)
8503 {
8504   GtkWidget *widget = GTK_WIDGET (button);
8505   GdkDevice *device;
8506
8507   device = gtk_get_current_event_device ();
8508   if (device == NULL)
8509     return;
8510
8511   if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
8512     device = gdk_device_get_associated_device (device);
8513
8514   data->is_toplevel = widget == data->toplevel_button;
8515
8516   if (!data->cursor)
8517     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8518                                                GDK_TARGET);
8519
8520   gdk_device_grab (device,
8521                    gtk_widget_get_window (widget),
8522                    GDK_OWNERSHIP_APPLICATION,
8523                    TRUE,
8524                    GDK_BUTTON_RELEASE_MASK,
8525                    data->cursor,
8526                    GDK_CURRENT_TIME);
8527
8528   g_signal_connect (button, "event",
8529                     G_CALLBACK (snapshot_widget_event), data);
8530
8531   gtk_grab_add (widget);
8532
8533   data->in_query = TRUE;
8534 }
8535
8536 static void
8537 create_snapshot (GtkWidget *widget)
8538 {
8539   static GtkWidget *window = NULL;
8540   GtkWidget *button;
8541   GtkWidget *vbox;
8542   struct SnapshotData *data;
8543
8544   data = g_new (struct SnapshotData, 1);
8545   data->window = &window;
8546   data->in_query = FALSE;
8547   data->cursor = NULL;
8548   data->handler = 0;
8549
8550   if (!window)
8551     {
8552       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8553
8554       gtk_window_set_screen (GTK_WINDOW (window),
8555                              gtk_widget_get_screen (widget));      
8556
8557       data->handler = g_signal_connect (window, "destroy",
8558                                         G_CALLBACK (destroy_snapshot_data),
8559                                         data);
8560
8561       gtk_window_set_title (GTK_WINDOW (window), "test snapshot");
8562       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8563
8564       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
8565       gtk_container_add (GTK_CONTAINER (window), vbox);
8566             
8567       button = gtk_button_new_with_label ("Snapshot widget");
8568       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8569       g_signal_connect (button, "clicked",
8570                         G_CALLBACK (snapshot_widget),
8571                         data);
8572       
8573       button = gtk_button_new_with_label ("Snapshot toplevel");
8574       data->toplevel_button = button;
8575       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8576       g_signal_connect (button, "clicked",
8577                         G_CALLBACK (snapshot_widget),
8578                         data);
8579     }
8580
8581   if (!gtk_widget_get_visible (window))
8582     gtk_widget_show_all (window);
8583   else
8584     gtk_widget_destroy (window);
8585   
8586 }
8587
8588 /*
8589  * Selection Test
8590  */
8591
8592 void
8593 selection_test_received (GtkWidget        *tree_view,
8594                          GtkSelectionData *selection_data)
8595 {
8596   GtkTreeModel *model;
8597   GtkListStore *store;
8598   GdkAtom *atoms;
8599   int i, l;
8600
8601   if (gtk_selection_data_get_length (selection_data) < 0)
8602     {
8603       g_print ("Selection retrieval failed\n");
8604       return;
8605     }
8606   if (gtk_selection_data_get_data_type (selection_data) != GDK_SELECTION_TYPE_ATOM)
8607     {
8608       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
8609       return;
8610     }
8611
8612   /* Clear out any current list items */
8613
8614   model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
8615   store = GTK_LIST_STORE (model);
8616   gtk_list_store_clear (store);
8617
8618   /* Add new items to list */
8619
8620   gtk_selection_data_get_targets (selection_data,
8621                                   &atoms, &l);
8622
8623   for (i = 0; i < l; i++)
8624     {
8625       char *name;
8626       GtkTreeIter iter;
8627
8628       name = gdk_atom_name (atoms[i]);
8629       if (name != NULL)
8630         {
8631           gtk_list_store_insert_with_values (store, &iter, i, 0, name, -1);
8632           g_free (name);
8633         }
8634       else
8635        gtk_list_store_insert_with_values (store, &iter, i, 0,  "(bad atom)", -1);
8636     }
8637
8638   return;
8639 }
8640
8641 void
8642 selection_test_get_targets (GtkWidget *widget, GtkWidget *tree_view)
8643 {
8644   static GdkAtom targets_atom = GDK_NONE;
8645
8646   if (targets_atom == GDK_NONE)
8647     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
8648
8649   gtk_selection_convert (tree_view, GDK_SELECTION_PRIMARY, targets_atom,
8650                          GDK_CURRENT_TIME);
8651 }
8652
8653 void
8654 create_selection_test (GtkWidget *widget)
8655 {
8656   static GtkWidget *window = NULL;
8657   GtkWidget *action_area, *content_area;
8658   GtkWidget *button;
8659   GtkWidget *vbox;
8660   GtkWidget *scrolled_win;
8661   GtkListStore* store;
8662   GtkWidget *tree_view;
8663   GtkTreeViewColumn *column;
8664   GtkCellRenderer *renderer;
8665   GtkWidget *label;
8666
8667   if (!window)
8668     {
8669       window = gtk_dialog_new ();
8670       
8671       gtk_window_set_screen (GTK_WINDOW (window),
8672                              gtk_widget_get_screen (widget));
8673
8674       g_signal_connect (window, "destroy",
8675                         G_CALLBACK (gtk_widget_destroyed),
8676                         &window);
8677
8678       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8679       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
8680
8681       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
8682       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8683
8684       /* Create the list */
8685
8686       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8687       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8688       gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
8689
8690       label = gtk_label_new ("Gets available targets for current selection");
8691       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
8692
8693       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
8694       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
8695                                       GTK_POLICY_AUTOMATIC, 
8696                                       GTK_POLICY_AUTOMATIC);
8697       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
8698       gtk_widget_set_size_request (scrolled_win, 100, 200);
8699
8700       store = gtk_list_store_new (1, G_TYPE_STRING);
8701       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
8702       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), tree_view);
8703
8704       renderer = gtk_cell_renderer_text_new ();
8705       column = gtk_tree_view_column_new_with_attributes ("Target", renderer,
8706                                                          "text", 0, NULL);
8707       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
8708
8709       g_signal_connect (tree_view, "selection_received",
8710                         G_CALLBACK (selection_test_received), NULL);
8711
8712       /* .. And create some buttons */
8713       button = gtk_button_new_with_label ("Get Targets");
8714       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8715
8716       g_signal_connect (button, "clicked",
8717                         G_CALLBACK (selection_test_get_targets), tree_view);
8718
8719       button = gtk_button_new_with_label ("Quit");
8720       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8721
8722       g_signal_connect_swapped (button, "clicked",
8723                                 G_CALLBACK (gtk_widget_destroy),
8724                                 window);
8725     }
8726
8727   if (!gtk_widget_get_visible (window))
8728     gtk_widget_show_all (window);
8729   else
8730     gtk_widget_destroy (window);
8731 }
8732
8733 /*
8734  * Test scrolling
8735  */
8736
8737 static int scroll_test_pos = 0.0;
8738
8739 static gint
8740 scroll_test_draw (GtkWidget     *widget,
8741                   cairo_t       *cr,
8742                   GtkAdjustment *adjustment)
8743 {
8744   gint i,j;
8745   gint imin, imax, jmin, jmax;
8746   GdkRectangle clip;
8747   
8748   gdk_cairo_get_clip_rectangle (cr, &clip);
8749
8750   imin = (clip.x) / 10;
8751   imax = (clip.x + clip.width + 9) / 10;
8752
8753   jmin = ((int)gtk_adjustment_get_value (adjustment) + clip.y) / 10;
8754   jmax = ((int)gtk_adjustment_get_value (adjustment) + clip.y + clip.height + 9) / 10;
8755
8756   for (i=imin; i<imax; i++)
8757     for (j=jmin; j<jmax; j++)
8758       if ((i+j) % 2)
8759         cairo_rectangle (cr, 10*i, 10*j - (int)gtk_adjustment_get_value (adjustment), 1+i%10, 1+j%10);
8760
8761   cairo_fill (cr);
8762
8763   return TRUE;
8764 }
8765
8766 static gint
8767 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
8768                     GtkAdjustment *adjustment)
8769 {
8770   gdouble new_value = gtk_adjustment_get_value (adjustment) + ((event->direction == GDK_SCROLL_UP) ?
8771                                     -gtk_adjustment_get_page_increment (adjustment) / 2:
8772                                     gtk_adjustment_get_page_increment (adjustment) / 2);
8773   new_value = CLAMP (new_value, gtk_adjustment_get_lower (adjustment), gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment));
8774   gtk_adjustment_set_value (adjustment, new_value);  
8775   
8776   return TRUE;
8777 }
8778
8779 static void
8780 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
8781                        GtkAdjustment *adjustment)
8782 {
8783   GtkAllocation allocation;
8784
8785   gtk_widget_get_allocation (widget, &allocation);
8786   gtk_adjustment_configure (adjustment,
8787                             gtk_adjustment_get_value (adjustment),
8788                             gtk_adjustment_get_lower (adjustment),
8789                             gtk_adjustment_get_upper (adjustment),
8790                             0.1 * allocation.height,
8791                             0.9 * allocation.height,
8792                             allocation.height);
8793 }
8794
8795 static void
8796 scroll_test_adjustment_changed (GtkAdjustment *adjustment, GtkWidget *widget)
8797 {
8798   GdkWindow *window;
8799   gint dy;
8800
8801   dy = scroll_test_pos - (int)gtk_adjustment_get_value (adjustment);
8802   scroll_test_pos = gtk_adjustment_get_value (adjustment);
8803
8804   if (!gtk_widget_is_drawable (widget))
8805     return;
8806
8807   window = gtk_widget_get_window (widget);
8808   gdk_window_scroll (window, 0, dy);
8809   gdk_window_process_updates (window, FALSE);
8810 }
8811
8812
8813 void
8814 create_scroll_test (GtkWidget *widget)
8815 {
8816   static GtkWidget *window = NULL;
8817   GtkWidget *action_area, *content_area;
8818   GtkWidget *hbox;
8819   GtkWidget *drawing_area;
8820   GtkWidget *scrollbar;
8821   GtkWidget *button;
8822   GtkAdjustment *adjustment;
8823   GdkGeometry geometry;
8824   GdkWindowHints geometry_mask;
8825
8826   if (!window)
8827     {
8828       window = gtk_dialog_new ();
8829
8830       gtk_window_set_screen (GTK_WINDOW (window),
8831                              gtk_widget_get_screen (widget));
8832
8833       g_signal_connect (window, "destroy",
8834                         G_CALLBACK (gtk_widget_destroyed),
8835                         &window);
8836
8837       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8838       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
8839
8840       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
8841       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8842
8843       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8844       gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
8845       gtk_widget_show (hbox);
8846
8847       drawing_area = gtk_drawing_area_new ();
8848       gtk_widget_set_size_request (drawing_area, 200, 200);
8849       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
8850       gtk_widget_show (drawing_area);
8851
8852       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
8853
8854       adjustment = gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0);
8855       scroll_test_pos = 0.0;
8856
8857       scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, adjustment);
8858       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
8859       gtk_widget_show (scrollbar);
8860
8861       g_signal_connect (drawing_area, "draw",
8862                         G_CALLBACK (scroll_test_draw), adjustment);
8863       g_signal_connect (drawing_area, "configure_event",
8864                         G_CALLBACK (scroll_test_configure), adjustment);
8865       g_signal_connect (drawing_area, "scroll_event",
8866                         G_CALLBACK (scroll_test_scroll), adjustment);
8867       
8868       g_signal_connect (adjustment, "value_changed",
8869                         G_CALLBACK (scroll_test_adjustment_changed),
8870                         drawing_area);
8871       
8872       /* .. And create some buttons */
8873
8874       button = gtk_button_new_with_label ("Quit");
8875       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8876
8877       g_signal_connect_swapped (button, "clicked",
8878                                 G_CALLBACK (gtk_widget_destroy),
8879                                 window);
8880       gtk_widget_show (button);
8881
8882       /* Set up gridded geometry */
8883
8884       geometry_mask = GDK_HINT_MIN_SIZE | 
8885                        GDK_HINT_BASE_SIZE | 
8886                        GDK_HINT_RESIZE_INC;
8887
8888       geometry.min_width = 20;
8889       geometry.min_height = 20;
8890       geometry.base_width = 0;
8891       geometry.base_height = 0;
8892       geometry.width_inc = 10;
8893       geometry.height_inc = 10;
8894       
8895       gtk_window_set_geometry_hints (GTK_WINDOW (window),
8896                                drawing_area, &geometry, geometry_mask);
8897     }
8898
8899   if (!gtk_widget_get_visible (window))
8900     gtk_widget_show (window);
8901   else
8902     gtk_widget_destroy (window);
8903 }
8904
8905 /*
8906  * Timeout Test
8907  */
8908
8909 static int timer = 0;
8910
8911 gint
8912 timeout_test (GtkWidget *label)
8913 {
8914   static int count = 0;
8915   static char buffer[32];
8916
8917   sprintf (buffer, "count: %d", ++count);
8918   gtk_label_set_text (GTK_LABEL (label), buffer);
8919
8920   return TRUE;
8921 }
8922
8923 void
8924 start_timeout_test (GtkWidget *widget,
8925                     GtkWidget *label)
8926 {
8927   if (!timer)
8928     {
8929       timer = g_timeout_add (100, (GSourceFunc)timeout_test, label);
8930     }
8931 }
8932
8933 void
8934 stop_timeout_test (GtkWidget *widget,
8935                    gpointer   data)
8936 {
8937   if (timer)
8938     {
8939       g_source_remove (timer);
8940       timer = 0;
8941     }
8942 }
8943
8944 void
8945 destroy_timeout_test (GtkWidget  *widget,
8946                       GtkWidget **window)
8947 {
8948   stop_timeout_test (NULL, NULL);
8949
8950   *window = NULL;
8951 }
8952
8953 void
8954 create_timeout_test (GtkWidget *widget)
8955 {
8956   static GtkWidget *window = NULL;
8957   GtkWidget *action_area, *content_area;
8958   GtkWidget *button;
8959   GtkWidget *label;
8960
8961   if (!window)
8962     {
8963       window = gtk_dialog_new ();
8964
8965       gtk_window_set_screen (GTK_WINDOW (window),
8966                              gtk_widget_get_screen (widget));
8967
8968       g_signal_connect (window, "destroy",
8969                         G_CALLBACK (destroy_timeout_test),
8970                         &window);
8971
8972       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8973       action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8974
8975       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
8976       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8977
8978       label = gtk_label_new ("count: 0");
8979       g_object_set (label, "margin", 10, NULL);
8980       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
8981       gtk_widget_show (label);
8982
8983       button = gtk_button_new_with_label ("close");
8984       g_signal_connect_swapped (button, "clicked",
8985                                 G_CALLBACK (gtk_widget_destroy),
8986                                 window);
8987       gtk_widget_set_can_default (button, TRUE);
8988       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8989       gtk_widget_grab_default (button);
8990       gtk_widget_show (button);
8991
8992       button = gtk_button_new_with_label ("start");
8993       g_signal_connect (button, "clicked",
8994                         G_CALLBACK(start_timeout_test),
8995                         label);
8996       gtk_widget_set_can_default (button, TRUE);
8997       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
8998       gtk_widget_show (button);
8999
9000       button = gtk_button_new_with_label ("stop");
9001       g_signal_connect (button, "clicked",
9002                         G_CALLBACK (stop_timeout_test),
9003                         NULL);
9004       gtk_widget_set_can_default (button, TRUE);
9005       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9006       gtk_widget_show (button);
9007     }
9008
9009   if (!gtk_widget_get_visible (window))
9010     gtk_widget_show (window);
9011   else
9012     gtk_widget_destroy (window);
9013 }
9014
9015 /*
9016  * Idle Test
9017  */
9018
9019 static int idle_id = 0;
9020
9021 static gint
9022 idle_test (GtkWidget *label)
9023 {
9024   static int count = 0;
9025   static char buffer[32];
9026
9027   sprintf (buffer, "count: %d", ++count);
9028   gtk_label_set_text (GTK_LABEL (label), buffer);
9029
9030   return G_SOURCE_CONTINUE;
9031 }
9032
9033 static void
9034 start_idle_test (GtkWidget *widget,
9035                  GtkWidget *label)
9036 {
9037   if (!idle_id)
9038     {
9039       idle_id = g_idle_add ((GSourceFunc) idle_test, label);
9040     }
9041 }
9042
9043 static void
9044 stop_idle_test (GtkWidget *widget,
9045                 gpointer   data)
9046 {
9047   if (idle_id)
9048     {
9049       g_source_remove (idle_id);
9050       idle_id = 0;
9051     }
9052 }
9053
9054 static void
9055 destroy_idle_test (GtkWidget  *widget,
9056                    GtkWidget **window)
9057 {
9058   stop_idle_test (NULL, NULL);
9059
9060   *window = NULL;
9061 }
9062
9063 static void
9064 toggle_idle_container (GObject *button,
9065                        GtkContainer *container)
9066 {
9067   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
9068 }
9069
9070 static void
9071 create_idle_test (GtkWidget *widget)
9072 {
9073   static GtkWidget *window = NULL;
9074   GtkWidget *button;
9075   GtkWidget *label;
9076   GtkWidget *container;
9077
9078   if (!window)
9079     {
9080       GtkWidget *action_area, *content_area;
9081       GtkWidget *button2;
9082       GtkWidget *frame;
9083       GtkWidget *box;
9084
9085       window = gtk_dialog_new ();
9086
9087       gtk_window_set_screen (GTK_WINDOW (window),
9088                              gtk_widget_get_screen (widget));
9089
9090       g_signal_connect (window, "destroy",
9091                         G_CALLBACK (destroy_idle_test),
9092                         &window);
9093
9094       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9095       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9096
9097       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
9098       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9099
9100       label = gtk_label_new ("count: 0");
9101       g_object_set (label, "margin", 10, NULL);
9102       gtk_widget_show (label);
9103       
9104       container =
9105         g_object_new (GTK_TYPE_BOX,
9106                         "visible", TRUE,
9107                         /* "GtkContainer::child", g_object_new (GTK_TYPE_HBOX,
9108                          * "GtkWidget::visible", TRUE,
9109                          */
9110                          "child", label,
9111                         /* NULL), */
9112                         NULL);
9113       gtk_box_pack_start (GTK_BOX (content_area), container, TRUE, TRUE, 0);
9114
9115       frame =
9116         g_object_new (GTK_TYPE_FRAME,
9117                         "border_width", 5,
9118                         "label", "Label Container",
9119                         "visible", TRUE,
9120                         "parent", content_area,
9121                         NULL);
9122       box =
9123         g_object_new (GTK_TYPE_BOX,
9124                         "visible", TRUE,
9125                         "parent", frame,
9126                         "orientation", GTK_ORIENTATION_VERTICAL,
9127                         NULL);
9128       button =
9129         g_object_connect (g_object_new (GTK_TYPE_RADIO_BUTTON,
9130                                           "label", "Resize-Parent",
9131                                           "user_data", (void*)GTK_RESIZE_PARENT,
9132                                           "visible", TRUE,
9133                                           "parent", box,
9134                                           NULL),
9135                           "signal::clicked", toggle_idle_container, container,
9136                           NULL);
9137       button = g_object_new (GTK_TYPE_RADIO_BUTTON,
9138                                "label", "Resize-Queue",
9139                                "user_data", (void*)GTK_RESIZE_QUEUE,
9140                                "group", button,
9141                                "visible", TRUE,
9142                                "parent", box,
9143                                NULL);
9144       g_object_connect (button,
9145                         "signal::clicked", toggle_idle_container, container,
9146                         NULL);
9147       button2 = g_object_new (GTK_TYPE_RADIO_BUTTON,
9148                                 "label", "Resize-Immediate",
9149                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
9150                                 NULL);
9151       g_object_connect (button2,
9152                         "signal::clicked", toggle_idle_container, container,
9153                         NULL);
9154       g_object_set (button2,
9155                     "group", button,
9156                     "visible", TRUE,
9157                     "parent", box,
9158                     NULL);
9159
9160       button = gtk_button_new_with_label ("close");
9161       g_signal_connect_swapped (button, "clicked",
9162                                 G_CALLBACK (gtk_widget_destroy),
9163                                 window);
9164       gtk_widget_set_can_default (button, TRUE);
9165       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9166       gtk_widget_grab_default (button);
9167       gtk_widget_show (button);
9168
9169       button = gtk_button_new_with_label ("start");
9170       g_signal_connect (button, "clicked",
9171                         G_CALLBACK (start_idle_test),
9172                         label);
9173       gtk_widget_set_can_default (button, TRUE);
9174       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9175       gtk_widget_show (button);
9176
9177       button = gtk_button_new_with_label ("stop");
9178       g_signal_connect (button, "clicked",
9179                         G_CALLBACK (stop_idle_test),
9180                         NULL);
9181       gtk_widget_set_can_default (button, TRUE);
9182       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9183       gtk_widget_show (button);
9184     }
9185
9186   if (!gtk_widget_get_visible (window))
9187     gtk_widget_show (window);
9188   else
9189     gtk_widget_destroy (window);
9190 }
9191
9192 /*
9193  * rc file test
9194  */
9195
9196 void
9197 create_rc_file (GtkWidget *widget)
9198 {
9199   static GtkWidget *window = NULL;
9200   GtkWidget *action_area, *content_area;
9201   GtkWidget *button;
9202   GtkWidget *frame;
9203   GtkWidget *vbox;
9204   GtkWidget *label;
9205
9206   if (!window)
9207     {
9208       window = gtk_dialog_new ();
9209
9210       gtk_window_set_screen (GTK_WINDOW (window),
9211                              gtk_widget_get_screen (widget));
9212
9213       g_signal_connect (window, "destroy",
9214                         G_CALLBACK (gtk_widget_destroyed),
9215                         &window);
9216
9217       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9218       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9219
9220       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
9221       gtk_box_pack_start (GTK_BOX (content_area), frame, FALSE, FALSE, 0);
9222
9223       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9224       gtk_container_add (GTK_CONTAINER (frame), vbox);
9225       
9226       label = gtk_label_new ("This label should be red");
9227       gtk_widget_set_name (label, "testgtk-red-label");
9228       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9229
9230       label = gtk_label_new ("This label should be green");
9231       gtk_widget_set_name (label, "testgtk-green-label");
9232       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9233
9234       label = gtk_label_new ("This label should be blue");
9235       gtk_widget_set_name (label, "testgtk-blue-label");
9236       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9237
9238       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
9239       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9240
9241       button = gtk_button_new_with_label ("Reload");
9242       g_signal_connect_swapped (button, "clicked",
9243                                 G_CALLBACK (gtk_style_context_reset_widgets),
9244                                 gtk_widget_get_screen (button));
9245       gtk_widget_set_can_default (button, TRUE);
9246       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9247       gtk_widget_grab_default (button);
9248
9249       button = gtk_button_new_with_label ("Close");
9250       g_signal_connect_swapped (button, "clicked",
9251                                 G_CALLBACK (gtk_widget_destroy),
9252                                 window);
9253       gtk_widget_set_can_default (button, TRUE);
9254       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9255     }
9256
9257   if (!gtk_widget_get_visible (window))
9258     gtk_widget_show_all (window);
9259   else
9260     gtk_widget_destroy (window);
9261 }
9262
9263 /*
9264  * Test of recursive mainloop
9265  */
9266
9267 void
9268 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
9269 {
9270   *window = NULL;
9271   gtk_main_quit ();
9272 }
9273
9274 void
9275 create_mainloop (GtkWidget *widget)
9276 {
9277   static GtkWidget *window = NULL;
9278   GtkWidget *action_area, *content_area;
9279   GtkWidget *label;
9280   GtkWidget *button;
9281
9282   if (!window)
9283     {
9284       window = gtk_dialog_new ();
9285
9286       gtk_window_set_screen (GTK_WINDOW (window),
9287                              gtk_widget_get_screen (widget));
9288
9289       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
9290
9291       g_signal_connect (window, "destroy",
9292                         G_CALLBACK (mainloop_destroyed),
9293                         &window);
9294
9295       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9296       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9297
9298       label = gtk_label_new ("In recursive main loop...");
9299       g_object_set (label, "margin", 20, NULL);
9300
9301       gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9302       gtk_widget_show (label);
9303
9304       button = gtk_button_new_with_label ("Leave");
9305       gtk_box_pack_start (GTK_BOX (action_area), button, FALSE, TRUE, 0);
9306
9307       g_signal_connect_swapped (button, "clicked",
9308                                 G_CALLBACK (gtk_widget_destroy),
9309                                 window);
9310
9311       gtk_widget_set_can_default (button, TRUE);
9312       gtk_widget_grab_default (button);
9313
9314       gtk_widget_show (button);
9315     }
9316
9317   if (!gtk_widget_get_visible (window))
9318     {
9319       gtk_widget_show (window);
9320
9321       g_print ("create_mainloop: start\n");
9322       gtk_main ();
9323       g_print ("create_mainloop: done\n");
9324     }
9325   else
9326     gtk_widget_destroy (window);
9327 }
9328
9329 static gboolean
9330 layout_draw_handler (GtkWidget *widget, cairo_t *cr)
9331 {
9332   GtkLayout *layout;
9333   GdkWindow *bin_window;
9334   GdkRectangle clip;
9335   gint i,j,x,y;
9336   gint imin, imax, jmin, jmax;
9337
9338   layout = GTK_LAYOUT (widget);
9339   bin_window = gtk_layout_get_bin_window (layout);
9340
9341   if (!gtk_cairo_should_draw_window (cr, bin_window))
9342     return FALSE;
9343   
9344   gdk_window_get_position (bin_window, &x, &y);
9345   cairo_translate (cr, x, y);
9346
9347   gdk_cairo_get_clip_rectangle (cr, &clip);
9348
9349   imin = (clip.x) / 10;
9350   imax = (clip.x + clip.width + 9) / 10;
9351
9352   jmin = (clip.y) / 10;
9353   jmax = (clip.y + clip.height + 9) / 10;
9354
9355   for (i=imin; i<imax; i++)
9356     for (j=jmin; j<jmax; j++)
9357       if ((i+j) % 2)
9358         cairo_rectangle (cr,
9359                          10*i, 10*j, 
9360                          1+i%10, 1+j%10);
9361   
9362   cairo_fill (cr);
9363
9364   return FALSE;
9365 }
9366
9367 void create_layout (GtkWidget *widget)
9368 {
9369   GtkAdjustment *hadjustment, *vadjustment;
9370   GtkLayout *layout;
9371   static GtkWidget *window = NULL;
9372   GtkWidget *layout_widget;
9373   GtkWidget *scrolledwindow;
9374   GtkWidget *button;
9375
9376   if (!window)
9377     {
9378       gchar buf[16];
9379
9380       gint i, j;
9381       
9382       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9383       gtk_window_set_screen (GTK_WINDOW (window),
9384                              gtk_widget_get_screen (widget));
9385
9386       g_signal_connect (window, "destroy",
9387                         G_CALLBACK (gtk_widget_destroyed),
9388                         &window);
9389
9390       gtk_window_set_title (GTK_WINDOW (window), "Layout");
9391       gtk_widget_set_size_request (window, 200, 200);
9392
9393       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
9394       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
9395                                            GTK_SHADOW_IN);
9396       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
9397                                          GTK_CORNER_TOP_RIGHT);
9398
9399       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
9400
9401       layout_widget = gtk_layout_new (NULL, NULL);
9402       layout = GTK_LAYOUT (layout_widget);
9403       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);
9404
9405       /* We set step sizes here since GtkLayout does not set
9406        * them itself.
9407        */
9408       hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout));
9409       vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (layout));
9410       gtk_adjustment_set_step_increment (hadjustment, 10.0);
9411       gtk_adjustment_set_step_increment (vadjustment, 10.0);
9412       gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (layout), hadjustment);
9413       gtk_scrollable_set_vadjustment (GTK_SCROLLABLE (layout), vadjustment);
9414
9415       gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
9416       g_signal_connect (layout, "draw",
9417                         G_CALLBACK (layout_draw_handler), NULL);
9418
9419       gtk_layout_set_size (layout, 1600, 128000);
9420
9421       for (i=0 ; i < 16 ; i++)
9422         for (j=0 ; j < 16 ; j++)
9423           {
9424             sprintf(buf, "Button %d, %d", i, j);
9425             if ((i + j) % 2)
9426               button = gtk_button_new_with_label (buf);
9427             else
9428               button = gtk_label_new (buf);
9429
9430             gtk_layout_put (layout, button, j*100, i*100);
9431           }
9432
9433       for (i=16; i < 1280; i++)
9434         {
9435           sprintf(buf, "Button %d, %d", i, 0);
9436           if (i % 2)
9437             button = gtk_button_new_with_label (buf);
9438           else
9439             button = gtk_label_new (buf);
9440
9441           gtk_layout_put (layout, button, 0, i*100);
9442         }
9443     }
9444
9445   if (!gtk_widget_get_visible (window))
9446     gtk_widget_show_all (window);
9447   else
9448     gtk_widget_destroy (window);
9449 }
9450
9451 #if 0
9452 /* FIXME: need to completely redo this for GtkStyleContext */
9453 void
9454 create_styles (GtkWidget *widget)
9455 {
9456   static GtkWidget *window = NULL;
9457   GtkWidget *content_area, *action_area;
9458   GtkWidget *label;
9459   GtkWidget *button;
9460   GtkWidget *entry;
9461   GtkWidget *vbox;
9462   static GdkRGBA red =    { 1,0,0,1 };
9463   static GdkRGBA green =  { 0,1,0,1 };
9464   static GdkRGBA blue =   { 0,0,1,1 };
9465   static GdkRGBA yellow = { 1,1,0,1 };
9466   static GdkRGBA cyan =   { 0,1,1,1 };
9467   PangoFontDescription *font_desc;
9468
9469   GtkRcStyle *rc_style;
9470
9471   if (!window)
9472     {
9473       window = gtk_dialog_new ();
9474       gtk_window_set_screen (GTK_WINDOW (window),
9475                              gtk_widget_get_screen (widget));
9476      
9477       g_signal_connect (window, "destroy",
9478                         G_CALLBACK (gtk_widget_destroyed),
9479                         &window);
9480
9481       content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9482       action_area = gtk_dialog_get_action_area (GTK_DIALOG (window));
9483
9484       button = gtk_button_new_with_label ("Close");
9485       g_signal_connect_swapped (button, "clicked",
9486                                 G_CALLBACK (gtk_widget_destroy),
9487                                 window);
9488       gtk_widget_set_can_default (button, TRUE);
9489       gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9490       gtk_widget_show (button);
9491
9492       vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
9493       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9494       gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
9495       
9496       label = gtk_label_new ("Font:");
9497       gtk_widget_set_halign (label, GTK_ALIGN_START);
9498       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9499       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9500
9501       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
9502
9503       button = gtk_button_new_with_label ("Some Text");
9504       gtk_widget_override_font (gtk_bin_get_child (GTK_BIN (button)), font_desc);
9505       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9506
9507       label = gtk_label_new ("Foreground:");
9508       gtk_widget_set_halign (label, GTK_ALIGN_START);
9509       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9510       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9511
9512       button = gtk_button_new_with_label ("Some Text");
9513       gtk_widget_override_color (gtk_bin_get_child (GTK_BIN (button)), 0, &red);
9514       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9515
9516       label = gtk_label_new ("Background:");
9517       gtk_widget_set_halign (label, GTK_ALIGN_START);
9518       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9519       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9520
9521       button = gtk_button_new_with_label ("Some Text");
9522       gtk_widget_override_background_color (button, 0, &green);
9523       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9524
9525       label = gtk_label_new ("Text:");
9526       gtk_widget_set_halign (label, GTK_ALIGN_START);
9527       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9528       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9529
9530       entry = gtk_entry_new ();
9531       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9532       gtk_widget_override_color (entry, 0, &blue);
9533       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9534
9535       label = gtk_label_new ("Base:");
9536       gtk_widget_set_halign (label, GTK_ALIGN_START);
9537       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9538       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9539
9540       entry = gtk_entry_new ();
9541       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9542       gtk_widget_override_background_color (entry, 0, &yellow);
9543       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9544
9545       label = gtk_label_new ("Cursor:");
9546       gtk_widget_set_halign (label, GTK_ALIGN_START);
9547       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9548       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9549
9550       entry = gtk_entry_new ();
9551       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
9552       gtk_widget_modify_cursor (entry, &red, &red);
9553       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9554
9555       label = gtk_label_new ("Multiple:");
9556       gtk_widget_set_halign (label, GTK_ALIGN_START);
9557       gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
9558       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9559
9560       button = gtk_button_new_with_label ("Some Text");
9561
9562       rc_style = gtk_rc_style_new ();
9563
9564       rc_style->font_desc = pango_font_description_copy (font_desc);
9565       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
9566       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
9567       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
9568       rc_style->fg[GTK_STATE_NORMAL] = yellow;
9569       rc_style->bg[GTK_STATE_NORMAL] = blue;
9570       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
9571       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
9572       rc_style->fg[GTK_STATE_ACTIVE] = red;
9573       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
9574       rc_style->xthickness = 5;
9575       rc_style->ythickness = 5;
9576
9577       gtk_widget_modify_style (button, rc_style);
9578       gtk_widget_modify_style (gtk_bin_get_child (GTK_BIN (button)), rc_style);
9579
9580       g_object_unref (rc_style);
9581       
9582       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9583     }
9584   
9585   if (!gtk_widget_get_visible (window))
9586     gtk_widget_show_all (window);
9587   else
9588     gtk_widget_destroy (window);
9589 }
9590 #endif
9591
9592 /*
9593  * Main Window and Exit
9594  */
9595
9596 void
9597 do_exit (GtkWidget *widget, GtkWidget *window)
9598 {
9599   gtk_widget_destroy (window);
9600   gtk_main_quit ();
9601 }
9602
9603 struct {
9604   char *label;
9605   void (*func) (GtkWidget *widget);
9606   gboolean do_not_benchmark;
9607 } buttons[] =
9608 {
9609   { "alpha window", create_alpha_window },
9610   { "big windows", create_big_windows },
9611   { "button box", create_button_box },
9612   { "buttons", create_buttons },
9613   { "check buttons", create_check_buttons },
9614   { "color selection", create_color_selection },
9615   { "composited window", create_composited_window },
9616   { "cursors", create_cursors },
9617   { "dialog", create_dialog },
9618   { "display & screen", create_display_screen, TRUE },
9619   { "entry", create_entry },
9620   { "event box", create_event_box },
9621   { "event watcher", create_event_watcher },
9622   { "expander", create_expander },
9623   { "flipping", create_flipping },
9624   { "focus", create_focus },
9625   { "font selection", create_font_selection },
9626   { "image", create_image },
9627   { "key lookup", create_key_lookup },
9628   { "labels", create_labels },
9629   { "layout", create_layout },
9630   { "menus", create_menus },
9631   { "message dialog", create_message_dialog },
9632   { "modal window", create_modal_window, TRUE },
9633   { "notebook", create_notebook },
9634   { "panes", create_panes },
9635   { "paned keyboard", create_paned_keyboard_navigation },
9636   { "pixbuf", create_pixbuf },
9637   { "progress bar", create_progress_bar },
9638   { "properties", create_properties },
9639   { "radio buttons", create_radio_buttons },
9640   { "range controls", create_range_controls },
9641   { "rc file", create_rc_file },
9642   { "reparent", create_reparent },
9643   { "resize grips", create_resize_grips },
9644   { "rotated label", create_rotated_label },
9645   { "rotated text", create_rotated_text },
9646   { "saved position", create_saved_position },
9647   { "scrolled windows", create_scrolled_windows },
9648   { "shapes", create_shapes },
9649   { "size groups", create_size_groups },
9650   { "snapshot", create_snapshot },
9651   { "spinbutton", create_spins },
9652   { "statusbar", create_statusbar },
9653 #if 0
9654   { "styles", create_styles },
9655 #endif
9656   { "test idle", create_idle_test },
9657   { "test mainloop", create_mainloop, TRUE },
9658   { "test scrolling", create_scroll_test },
9659   { "test selection", create_selection_test },
9660   { "test timeout", create_timeout_test },
9661   { "toggle buttons", create_toggle_buttons },
9662   { "toolbar", create_toolbar },
9663   { "tooltips", create_tooltips },
9664   { "WM hints", create_wmhints },
9665   { "window sizing", create_window_sizing },
9666   { "window states", create_window_states }
9667 };
9668 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
9669
9670 void
9671 create_main_window (void)
9672 {
9673   GtkWidget *window;
9674   GtkWidget *box1;
9675   GtkWidget *box2;
9676   GtkWidget *scrolled_window;
9677   GtkWidget *button;
9678   GtkWidget *label;
9679   gchar buffer[64];
9680   GtkWidget *separator;
9681   GdkGeometry geometry;
9682   int i;
9683
9684   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9685   gtk_widget_set_name (window, "main_window");
9686   gtk_window_move (GTK_WINDOW (window), 50, 20);
9687   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
9688
9689   geometry.min_width = -1;
9690   geometry.min_height = -1;
9691   geometry.max_width = -1;
9692   geometry.max_height = G_MAXSHORT;
9693   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
9694                                  &geometry,
9695                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
9696
9697   g_signal_connect (window, "destroy",
9698                     G_CALLBACK (gtk_main_quit),
9699                     NULL);
9700   g_signal_connect (window, "delete-event",
9701                     G_CALLBACK (gtk_false),
9702                     NULL);
9703
9704   box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9705   gtk_container_add (GTK_CONTAINER (window), box1);
9706
9707   if (gtk_micro_version > 0)
9708     sprintf (buffer,
9709              "Gtk+ v%d.%d.%d",
9710              gtk_get_major_version (),
9711              gtk_get_minor_version (),
9712              gtk_get_micro_version ());
9713   else
9714     sprintf (buffer,
9715              "Gtk+ v%d.%d",
9716              gtk_get_major_version (),
9717              gtk_get_minor_version ());
9718
9719   label = gtk_label_new (buffer);
9720   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
9721   gtk_widget_set_name (label, "testgtk-version-label");
9722
9723   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
9724   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
9725   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
9726                                   GTK_POLICY_NEVER, 
9727                                   GTK_POLICY_AUTOMATIC);
9728   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
9729
9730   box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9731   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9732   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
9733   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
9734                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
9735   gtk_widget_show (box2);
9736
9737   for (i = 0; i < nbuttons; i++)
9738     {
9739       button = gtk_button_new_with_label (buttons[i].label);
9740       if (buttons[i].func)
9741         g_signal_connect (button, 
9742                           "clicked", 
9743                           G_CALLBACK(buttons[i].func),
9744                           NULL);
9745       else
9746         gtk_widget_set_sensitive (button, FALSE);
9747       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9748     }
9749
9750   separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
9751   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9752
9753   box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
9754   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9755   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9756
9757   button = gtk_button_new_with_mnemonic ("_Close");
9758   g_signal_connect (button, "clicked",
9759                     G_CALLBACK (do_exit),
9760                     window);
9761   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9762   gtk_widget_set_can_default (button, TRUE);
9763   gtk_widget_grab_default (button);
9764
9765   gtk_widget_show_all (window);
9766 }
9767
9768 static void
9769 test_init (void)
9770 {
9771   if (g_file_test ("../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
9772     g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
9773 }
9774
9775 static char *
9776 pad (const char *str, int to)
9777 {
9778   static char buf[256];
9779   int len = strlen (str);
9780   int i;
9781
9782   for (i = 0; i < to; i++)
9783     buf[i] = ' ';
9784
9785   buf[to] = '\0';
9786
9787   memcpy (buf, str, len);
9788
9789   return buf;
9790 }
9791
9792 static void
9793 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
9794 {
9795   fn (widget); /* on */
9796   while (g_main_context_iteration (NULL, FALSE));
9797   fn (widget); /* off */
9798   while (g_main_context_iteration (NULL, FALSE));
9799 }
9800
9801 void
9802 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
9803 {
9804   GTimeVal tv0, tv1;
9805   double dt_first;
9806   double dt;
9807   int n;
9808   static gboolean printed_headers = FALSE;
9809
9810   if (!printed_headers) {
9811     g_print ("Test                 Iters      First      Other\n");
9812     g_print ("-------------------- ----- ---------- ----------\n");
9813     printed_headers = TRUE;
9814   }
9815
9816   g_get_current_time (&tv0);
9817   bench_iteration (widget, fn); 
9818   g_get_current_time (&tv1);
9819
9820   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
9821         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
9822
9823   g_get_current_time (&tv0);
9824   for (n = 0; n < num - 1; n++)
9825     bench_iteration (widget, fn); 
9826   g_get_current_time (&tv1);
9827   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
9828         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
9829
9830   g_print ("%s %5d ", pad (name, 20), num);
9831   if (num > 1)
9832     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
9833   else
9834     g_print ("%10.1f\n", dt_first);
9835 }
9836
9837 void
9838 do_bench (char* what, int num)
9839 {
9840   int i;
9841   GtkWidget *widget;
9842   void (* fn) (GtkWidget *widget);
9843   fn = NULL;
9844   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9845
9846   if (g_ascii_strcasecmp (what, "ALL") == 0)
9847     {
9848       for (i = 0; i < nbuttons; i++)
9849         {
9850           if (!buttons[i].do_not_benchmark)
9851             do_real_bench (widget, buttons[i].func, buttons[i].label, num);
9852         }
9853
9854       return;
9855     }
9856   else
9857     {
9858       for (i = 0; i < nbuttons; i++)
9859         {
9860           if (strcmp (buttons[i].label, what) == 0)
9861             {
9862               fn = buttons[i].func;
9863               break;
9864             }
9865         }
9866       
9867       if (!fn)
9868         g_print ("Can't bench: \"%s\" not found.\n", what);
9869       else
9870         do_real_bench (widget, fn, buttons[i].label, num);
9871     }
9872 }
9873
9874 void 
9875 usage (void)
9876 {
9877   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
9878   exit (1);
9879 }
9880
9881 int
9882 main (int argc, char *argv[])
9883 {
9884   GtkCssProvider *provider, *memory_provider;
9885   GdkDisplay *display;
9886   GdkScreen *screen;
9887   GtkBindingSet *binding_set;
9888   int i;
9889   gboolean done_benchmarks = FALSE;
9890
9891   srand (time (NULL));
9892
9893   test_init ();
9894
9895   g_set_application_name ("GTK+ Test Program");
9896
9897   gtk_init (&argc, &argv);
9898
9899   provider = gtk_css_provider_new ();
9900
9901   /* Check to see if we are being run from the correct
9902    * directory.
9903    */
9904   if (file_exists ("testgtk.css"))
9905     gtk_css_provider_load_from_path (provider, "testgtk.css", NULL);
9906   else if (file_exists ("tests/testgtk.css"))
9907     gtk_css_provider_load_from_path (provider, "tests/testgtk.css", NULL);
9908   else
9909     g_warning ("Couldn't find file \"testgtk.css\".");
9910
9911   display = gdk_display_get_default ();
9912   screen = gdk_display_get_default_screen (display);
9913
9914   gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
9915                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
9916   g_object_unref (provider);
9917
9918   gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
9919                                         GDK_CONTROL_MASK |
9920                                         GDK_MOD1_MASK | 
9921                                         GDK_META_MASK |
9922                                         GDK_SUPER_MASK |
9923                                         GDK_HYPER_MASK |
9924                                         GDK_MOD4_MASK);
9925   /*  benchmarking
9926    */
9927   for (i = 1; i < argc; i++)
9928     {
9929       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
9930         {
9931           int num = 1;
9932           char *nextarg;
9933           char *what;
9934           char *count;
9935           
9936           nextarg = strchr (argv[i], '=');
9937           if (nextarg)
9938             nextarg++;
9939           else
9940             {
9941               i++;
9942               if (i == argc)
9943                 usage ();
9944               nextarg = argv[i];
9945             }
9946
9947           count = strchr (nextarg, ':');
9948           if (count)
9949             {
9950               what = g_strndup (nextarg, count - nextarg);
9951               count++;
9952               num = atoi (count);
9953               if (num <= 0)
9954                 usage ();
9955             }
9956           else
9957             what = g_strdup (nextarg);
9958
9959           do_bench (what, num ? num : 1);
9960           done_benchmarks = TRUE;
9961         }
9962       else
9963         usage ();
9964     }
9965   if (done_benchmarks)
9966     return 0;
9967
9968   /* bindings test
9969    */
9970   binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_WIDGET));
9971   gtk_binding_entry_add_signal (binding_set,
9972                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
9973                                 "debug_msg",
9974                                 1,
9975                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
9976
9977   memory_provider = gtk_css_provider_new ();
9978   gtk_css_provider_load_from_data (memory_provider,
9979                                    "#testgtk-version-label {\n"
9980                                    "  color: #f00;\n"
9981                                    "  font: Sans 18;\n"
9982                                    "}",
9983                                    -1, NULL);
9984   gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (memory_provider),
9985                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
9986
9987   create_main_window ();
9988
9989   gtk_main ();
9990
9991   if (1)
9992     {
9993       while (g_main_context_pending (NULL))
9994         g_main_context_iteration (NULL, FALSE);
9995 #if 0
9996       sleep (1);
9997       while (g_main_context_pending (NULL))
9998         g_main_context_iteration (NULL, FALSE);
9999 #endif
10000     }
10001   return 0;
10002 }