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