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