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