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