]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
Revert previous commit; the API is not yet finalized - see bug #166995.
[~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 #undef GTK_DISABLE_DEPRECATED
28
29 #include <config.h>
30
31 #undef  G_LOG_DOMAIN
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sys/stat.h>
37 #include <math.h>
38 #include <time.h>
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #define GTK_ENABLE_BROKEN
44 #include "gtk/gtk.h"
45 #include "gdk/gdk.h"
46 #include "gdk/gdkkeysyms.h"
47
48 #ifdef G_OS_WIN32
49 #define sleep(n) _sleep(n)
50 #endif
51
52 #include "prop-editor.h"
53
54 #include "circles.xbm"
55 #include "test.xpm"
56
57 gboolean
58 file_exists (const char *filename)
59 {
60   struct stat statbuf;
61
62   return stat (filename, &statbuf) == 0;
63 }
64
65 GtkWidget *
66 shape_create_icon (GdkScreen *screen,
67                    char      *xpm_file,
68                    gint       x,
69                    gint       y,
70                    gint       px,
71                    gint       py,
72                    gint       window_type);
73
74 static GtkWidget *
75 build_option_menu (gchar           *items[],
76                    gint             num_items,
77                    gint             history,
78                    void           (*func) (GtkWidget *widget, gpointer data),
79                    gpointer         data);
80
81 /* macro, structure and variables used by tree window demos */
82 #define DEFAULT_NUMBER_OF_ITEM  3
83 #define DEFAULT_RECURSION_LEVEL 3
84
85 struct {
86   GSList* selection_mode_group;
87   GtkWidget* single_button;
88   GtkWidget* browse_button;
89   GtkWidget* multiple_button;
90   GtkWidget* draw_line_button;
91   GtkWidget* view_line_button;
92   GtkWidget* no_root_item_button;
93   GtkWidget* nb_item_spinner;
94   GtkWidget* recursion_spinner;
95 } sTreeSampleSelection;
96
97 typedef struct sTreeButtons {
98   guint nb_item_add;
99   GtkWidget* add_button;
100   GtkWidget* remove_button;
101   GtkWidget* subtree_button;
102 } sTreeButtons;
103 /* end of tree section */
104
105 static GtkWidget *
106 build_option_menu (gchar           *items[],
107                    gint             num_items,
108                    gint             history,
109                    void           (*func)(GtkWidget *widget, gpointer data),
110                    gpointer         data)
111 {
112   GtkWidget *omenu;
113   GtkWidget *menu;
114   GtkWidget *menu_item;
115   GSList *group;
116   gint i;
117
118   omenu = gtk_option_menu_new ();
119   g_signal_connect (omenu, "changed",
120                     G_CALLBACK (func), data);
121       
122   menu = gtk_menu_new ();
123   group = NULL;
124   
125   for (i = 0; i < num_items; i++)
126     {
127       menu_item = gtk_radio_menu_item_new_with_label (group, items[i]);
128       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
129       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
130       if (i == history)
131         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
132       gtk_widget_show (menu_item);
133     }
134
135   gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
136   gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), history);
137   
138   return omenu;
139 }
140
141 static void
142 destroy_tooltips (GtkWidget *widget, GtkWindow **window)
143 {
144   GtkTooltips *tt = g_object_get_data (G_OBJECT (*window), "tooltips");
145   g_object_unref (tt);
146   *window = NULL;
147 }
148
149
150 /*
151  * Windows with an alpha channel
152  */
153
154
155 static gboolean
156 on_alpha_window_expose (GtkWidget      *widget,
157                         GdkEventExpose *expose)
158 {
159   cairo_t *cr;
160   cairo_pattern_t *pattern;
161   int radius;
162
163   cr = gdk_cairo_create (widget->window);
164
165   radius = MIN (widget->allocation.width, widget->allocation.height) / 2;
166   pattern = cairo_pattern_create_radial (widget->allocation.width / 2,
167                                          widget->allocation.height / 2,
168                                          0.0,
169                                          widget->allocation.width / 2,
170                                          widget->allocation.height / 2,
171                                          radius * 1.33);
172
173   if (gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)) &&
174       gtk_widget_is_composited (widget))
175     cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
176   else
177     cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
178     
179   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
180   cairo_paint (cr);
181   
182   cairo_pattern_add_color_stop_rgba (pattern, 0.0,
183                                      1.0, 0.75, 0.0, 1.0); /* solid orange */
184   cairo_pattern_add_color_stop_rgba (pattern, 1.0,
185                                      1.0, 0.75, 0.0, 0.0); /* transparent orange */
186
187   cairo_set_source (cr, pattern);
188   cairo_pattern_destroy (pattern);
189   
190   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
191   cairo_paint (cr);
192
193   cairo_destroy (cr);
194
195   return FALSE;
196 }
197
198 static GtkWidget *
199 build_alpha_widgets (void)
200 {
201   GtkWidget *table;
202   GtkWidget *radio_button;
203   GtkWidget *hbox;
204   GtkWidget *label;
205   GtkWidget *entry;
206
207   table = gtk_table_new (1, 1, FALSE);
208
209   radio_button = gtk_radio_button_new_with_label (NULL, "Red");
210   gtk_table_attach (GTK_TABLE (table),
211                     radio_button,
212                     0, 1,                  0, 1,
213                     GTK_EXPAND | GTK_FILL, 0,
214                     0,                     0);
215
216   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
217   gtk_table_attach (GTK_TABLE (table),
218                     radio_button,
219                     0, 1,                  1, 2,
220                     GTK_EXPAND | GTK_FILL, 0,
221                     0,                     0);
222
223   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
224   gtk_table_attach (GTK_TABLE (table),
225                     radio_button,
226                     0, 1,                  2, 3,
227                     GTK_EXPAND | GTK_FILL, 0,
228                     0,                     0);
229
230   gtk_table_attach (GTK_TABLE (table),
231                     gtk_check_button_new_with_label ("Sedentary"),
232                     1, 2,                  0, 1,
233                     GTK_EXPAND | GTK_FILL, 0,
234                     0,                     0);
235   gtk_table_attach (GTK_TABLE (table),
236                     gtk_check_button_new_with_label ("Nocturnal"),
237                     1, 2,                  1, 2,
238                     GTK_EXPAND | GTK_FILL, 0,
239                     0,                     0);
240   gtk_table_attach (GTK_TABLE (table),
241                     gtk_check_button_new_with_label ("Compulsive"),
242                     1, 2,                  2, 3,
243                     GTK_EXPAND | GTK_FILL, 0,
244                     0,                     0);
245
246   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
247   gtk_table_attach (GTK_TABLE (table),
248                     radio_button,
249                     0, 1,                  1, 2,
250                     GTK_EXPAND | GTK_FILL, 0,
251                     0,                     0);
252
253   radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
254   gtk_table_attach (GTK_TABLE (table),
255                     radio_button,
256                     0, 1,                  2, 3,
257                     GTK_EXPAND | GTK_FILL, 0,
258                     0,                     0);
259   
260   hbox = gtk_hbox_new (FALSE, 0);
261   label = gtk_label_new (NULL);
262   gtk_label_set_markup (GTK_LABEL (label), "<i>Entry: </i>");
263   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
264   entry = gtk_entry_new ();
265   gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
266   gtk_table_attach (GTK_TABLE (table),
267                     hbox,
268                     0, 1,                  3, 4,
269                     GTK_EXPAND | GTK_FILL, 0,
270                     0,                     0);
271   
272   return table;
273 }
274
275 static gboolean
276 on_alpha_drawing_expose (GtkWidget      *widget,
277                          GdkEventExpose *expose)
278 {
279   int x = widget->allocation.x;
280   int y = widget->allocation.y;
281   int width = widget->allocation.width;
282   int height = widget->allocation.height;
283   GdkPixbuf *pixbuf;
284   guchar *buffer;
285   guchar *p;
286   int i, j;
287
288   buffer = g_malloc (64 * 64 * 4);
289   
290   gdk_draw_rectangle (widget->window, widget->style->black_gc, FALSE,
291                       x,         y,
292                       width - 1, height - 1);
293
294   p = buffer;
295   for (i = 0; i < 64; i++) {
296     for (j = 0; j < 64; j++) {
297       *(p++) = i * 4 + 3;
298       *(p++) = 0;
299       *(p++) = j + 4 + 3;
300       *(p++) = MIN (255, ((32 - i) * (32 - i) + (32 - j) * (32 - j)) / 8);
301     }
302   }
303   p++;
304
305   gdk_draw_rgb_32_image (widget->window, widget->style->black_gc,
306                          x + 18, y + (height - 64) /2,
307                          64, 64, GDK_RGB_DITHER_NORMAL, buffer, 64 * 4);
308
309   pixbuf = gdk_pixbuf_new_from_data (buffer, GDK_COLORSPACE_RGB, TRUE,
310                                      8, 64, 64, 4 * 64, NULL, NULL);
311
312   gdk_draw_pixbuf (widget->window, widget->style->black_gc, pixbuf,
313                    0, 0, x + width - 18 - 64, y + (height - 64) /2,
314                    64, 64, GDK_RGB_DITHER_NORMAL, 0, 0);
315
316   g_object_unref (pixbuf);
317
318   g_free (buffer);
319   
320   return FALSE;
321 }
322
323 static GtkWidget *
324 build_alpha_drawing ()
325 {
326   GtkWidget *hbox;
327
328   hbox = gtk_hbox_new (FALSE, 0);
329   gtk_widget_set_size_request (hbox, 100, 100);
330
331   g_signal_connect (hbox, "expose-event",
332                     G_CALLBACK (on_alpha_drawing_expose), NULL);
333
334   return hbox;
335 }
336
337 static void
338 on_alpha_screen_changed (GtkWidget *widget,
339                          GdkScreen *old_screen,
340                          GtkWidget *label)
341 {
342   GdkScreen *screen = gtk_widget_get_screen (widget);
343   GdkColormap *colormap = gdk_screen_get_rgba_colormap (screen);
344
345   if (!colormap)
346     {
347       colormap = gdk_screen_get_rgb_colormap (screen);
348       gtk_label_set_markup (GTK_LABEL (label), "<b>Screen doesn't support alpha</b>");
349     }
350   else
351     {
352       gtk_label_set_markup (GTK_LABEL (label), "<b>Screen supports alpha</b>");
353     }
354
355   gtk_widget_set_colormap (widget, colormap);
356 }
357
358 static void
359 on_composited_changed (GtkWidget *window,
360                       GtkLabel *label)
361 {
362   gboolean is_composited = gtk_widget_is_composited (window);
363
364   if (is_composited)
365     gtk_label_set_text (label, "Composited");
366   else
367     gtk_label_set_text (label, "Not composited");
368 }
369
370 void
371 create_alpha_window (GtkWidget *widget)
372 {
373   static GtkWidget *window;
374
375   if (!window)
376     {
377       GtkWidget *vbox;
378       GtkWidget *label;
379       
380       window = gtk_dialog_new_with_buttons ("Alpha Window",
381                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
382                                             GTK_STOCK_CLOSE, 0,
383                                             NULL);
384
385       gtk_widget_set_app_paintable (window, TRUE);
386       g_signal_connect (window, "expose-event",
387                         G_CALLBACK (on_alpha_window_expose), NULL);
388       
389       vbox = gtk_vbox_new (FALSE, 8);
390       gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
391       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
392                           TRUE, TRUE, 0);
393
394       label = gtk_label_new (NULL);
395       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
396       on_alpha_screen_changed (window, NULL, label);
397       g_signal_connect (window, "screen-changed",
398                         G_CALLBACK (on_alpha_screen_changed), label);
399       
400       label = gtk_label_new (NULL);
401       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
402       on_composited_changed (window, GTK_LABEL (label));
403       g_signal_connect (window, "composited_changed", G_CALLBACK (on_composited_changed), label);
404       
405       gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
406       gtk_box_pack_start (GTK_BOX (vbox), build_alpha_drawing (), TRUE, TRUE, 0);
407
408       g_signal_connect (window, "destroy",
409                         G_CALLBACK (gtk_widget_destroyed),
410                         &window);
411       
412       g_signal_connect (window, "response",
413                         G_CALLBACK (gtk_widget_destroy),
414                         NULL); 
415     }
416
417   if (!GTK_WIDGET_VISIBLE (window))
418     gtk_widget_show_all (window);
419   else
420     gtk_widget_destroy (window);
421 }
422
423 /*
424  * Composited non-toplevel window
425  */
426
427 /* The expose event handler for the event box.
428  *
429  * This function simply draws a transparency onto a widget on the area
430  * for which it receives expose events.  This is intended to give the
431  * event box a "transparent" background.
432  *
433  * In order for this to work properly, the widget must have an RGBA
434  * colourmap.  The widget should also be set as app-paintable since it
435  * doesn't make sense for GTK to draw a background if we are drawing it
436  * (and because GTK might actually replace our transparency with its
437  * default background colour).
438  */
439 static gboolean
440 transparent_expose (GtkWidget *widget,
441                     GdkEventExpose *event)
442 {
443   cairo_t *cr;
444
445   cr = gdk_cairo_create (widget->window);
446   cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
447   gdk_cairo_region (cr, event->region);
448   cairo_fill (cr);
449   cairo_destroy (cr);
450
451   return FALSE;
452 }
453
454 /* The expose event handler for the window.
455  *
456  * This function performs the actual compositing of the event box onto
457  * the already-existing background of the window at 50% normal opacity.
458  *
459  * In this case we do not want app-paintable to be set on the widget
460  * since we want it to draw its own (red) background.  Because of this,
461  * however, we must ensure that we use g_signal_register_after so that
462  * this handler is called after the red has been drawn.  If it was
463  * called before then GTK would just blindly paint over our work.
464  */
465 static gboolean
466 window_expose_event (GtkWidget *widget,
467                      GdkEventExpose *event)
468 {
469   GdkRegion *region;
470   GtkWidget *child;
471   cairo_t *cr;
472
473   /* get our child (in this case, the event box) */ 
474   child = gtk_bin_get_child (GTK_BIN (widget));
475
476   /* create a cairo context to draw to the window */
477   cr = gdk_cairo_create (widget->window);
478
479   /* the source data is the (composited) event box */
480   gdk_cairo_set_source_pixmap (cr, child->window,
481                                child->allocation.x,
482                                child->allocation.y);
483
484   /* draw no more than our expose event intersects our child */
485   region = gdk_region_rectangle (&child->allocation);
486   gdk_region_intersect (region, event->region);
487   gdk_cairo_region (cr, region);
488   cairo_clip (cr);
489
490   /* composite, with a 50% opacity */
491   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
492   cairo_paint_with_alpha (cr, 0.5);
493
494   /* we're done */
495   cairo_destroy (cr);
496
497   return FALSE;
498 }
499
500 void
501 create_composited_window (GtkWidget *widget)
502 {
503   static GtkWidget *window;
504
505   if (!window)
506     {
507       GtkWidget *event, *button;
508       GdkScreen *screen;
509       GdkColormap *rgba;
510       GdkColor red;
511
512       /* make the widgets */
513       button = gtk_button_new_with_label ("A Button");
514       event = gtk_event_box_new ();
515       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
516
517       /* put a red background on the window */
518       gdk_color_parse ("red", &red);
519       gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &red);
520
521       /* set the colourmap for the event box.
522        * must be done before the event box is realised.
523        */
524       screen = gtk_widget_get_screen (event);
525       rgba = gdk_screen_get_rgba_colormap (screen);
526       gtk_widget_set_colormap (event, rgba);
527
528       /* set our event box to have a fully-transparent background
529        * drawn on it.  currently there is no way to simply tell gtk
530        * that "transparency" is the background colour for a widget.
531        */
532       gtk_widget_set_app_paintable (GTK_WIDGET (event), TRUE);
533       g_signal_connect (event, "expose-event",
534                         G_CALLBACK (transparent_expose), NULL);
535
536       /* put them inside one another */
537       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
538       gtk_container_add (GTK_CONTAINER (window), event);
539       gtk_container_add (GTK_CONTAINER (event), button);
540
541       /* realise and show everything */
542       gtk_widget_realize (button);
543
544       /* set the event box GdkWindow to be composited.
545        * obviously must be performed after event box is realised.
546        */
547       gdk_window_set_composited (event->window, TRUE);
548
549       /* set up the compositing handler.
550        * note that we do _after so that the normal (red) background is drawn
551        * by gtk before our compositing occurs.
552        */
553       g_signal_connect_after (window, "expose-event",
554                               G_CALLBACK (window_expose_event), NULL);
555     }
556
557   if (!GTK_WIDGET_VISIBLE (window))
558     gtk_widget_show_all (window);
559   else
560     gtk_widget_destroy (window);
561 }
562
563 /*
564  * Big windows and guffaw scrolling
565  */
566
567 static gboolean
568 pattern_expose (GtkWidget      *widget,
569                 GdkEventExpose *event,
570                 gpointer        data)
571 {
572   GdkColor *color;
573   GdkWindow *window = event->window;
574
575   color = g_object_get_data (G_OBJECT (window), "pattern-color");
576   if (color)
577     {
578       GdkGC *tmp_gc = gdk_gc_new (window);
579       gdk_gc_set_rgb_fg_color (tmp_gc, color);
580
581       gdk_draw_rectangle (window, tmp_gc, TRUE,
582                           event->area.x, event->area.y,
583                           event->area.width, event->area.height);
584
585       g_object_unref (tmp_gc);
586     }
587
588   return FALSE;
589 }
590
591 static void
592 pattern_set_bg (GtkWidget   *widget,
593                 GdkWindow   *child,
594                 gint         level)
595 {
596   static const GdkColor colors[] = {
597     { 0, 0x4444, 0x4444, 0xffff },
598     { 0, 0x8888, 0x8888, 0xffff },
599     { 0, 0xaaaa, 0xaaaa, 0xffff }
600   };
601     
602   g_object_set_data (G_OBJECT (child), "pattern-color", (gpointer) &colors[level]);
603   gdk_window_set_user_data (child, widget);
604 }
605
606 static void
607 create_pattern (GtkWidget   *widget,
608                 GdkWindow   *parent,
609                 gint         level,
610                 gint         width,
611                 gint         height)
612 {
613   gint h = 1;
614   gint i = 0;
615     
616   GdkWindow *child;
617
618   while (2 * h <= height)
619     {
620       gint w = 1;
621       gint j = 0;
622       
623       while (2 * w <= width)
624         {
625           if ((i + j) % 2 == 0)
626             {
627               gint x = w  - 1;
628               gint y = h - 1;
629               
630               GdkWindowAttr attributes;
631
632               attributes.window_type = GDK_WINDOW_CHILD;
633               attributes.x = x;
634               attributes.y = y;
635               attributes.width = w;
636               attributes.height = h;
637               attributes.wclass = GDK_INPUT_OUTPUT;
638               attributes.event_mask = GDK_EXPOSURE_MASK;
639               attributes.visual = gtk_widget_get_visual (widget);
640               attributes.colormap = gtk_widget_get_colormap (widget);
641               
642               child = gdk_window_new (parent, &attributes,
643                                       GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP);
644
645               pattern_set_bg (widget, child, level);
646
647               if (level < 2)
648                 create_pattern (widget, child, level + 1, w, h);
649
650               gdk_window_show (child);
651             }
652           j++;
653           w *= 2;
654         }
655       i++;
656       h *= 2;
657     }
658 }
659
660 #define PATTERN_SIZE (1 << 18)
661
662 static void
663 pattern_hadj_changed (GtkAdjustment *adj,
664                       GtkWidget     *darea)
665 {
666   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
667   gint new_value = adj->value;
668
669   if (GTK_WIDGET_REALIZED (darea))
670     {
671       gdk_window_scroll (darea->window, *old_value - new_value, 0);
672       *old_value = new_value;
673     }
674 }
675
676 static void
677 pattern_vadj_changed (GtkAdjustment *adj,
678                       GtkWidget *darea)
679 {
680   gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value");
681   gint new_value = adj->value;
682
683   if (GTK_WIDGET_REALIZED (darea))
684     {
685       gdk_window_scroll (darea->window, 0, *old_value - new_value);
686       *old_value = new_value;
687     }
688 }
689
690 static void
691 pattern_realize (GtkWidget *widget,
692                  gpointer   data)
693 {
694   pattern_set_bg (widget, widget->window, 0);
695   create_pattern (widget, widget->window, 1, PATTERN_SIZE, PATTERN_SIZE);
696 }
697
698 static void 
699 create_big_windows (GtkWidget *widget)
700 {
701   static GtkWidget *window = NULL;
702   GtkWidget *darea, *table, *scrollbar;
703   GtkWidget *eventbox;
704   GtkAdjustment *hadj;
705   GtkAdjustment *vadj;
706   static gint current_x;
707   static gint current_y;
708  
709   if (!window)
710     {
711       current_x = 0;
712       current_y = 0;
713       
714       window = gtk_dialog_new_with_buttons ("Big Windows",
715                                             NULL, 0,
716                                             GTK_STOCK_CLOSE,
717                                             GTK_RESPONSE_NONE,
718                                             NULL);
719  
720       gtk_window_set_screen (GTK_WINDOW (window),
721                              gtk_widget_get_screen (widget));
722
723       gtk_window_set_default_size (GTK_WINDOW (window), 200, 300);
724
725       g_signal_connect (window, "destroy",
726                         G_CALLBACK (gtk_widget_destroyed),
727                         &window);
728
729       g_signal_connect (window, "response",
730                         G_CALLBACK (gtk_widget_destroy),
731                         NULL);
732
733       table = gtk_table_new (2, 2, FALSE);
734       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox),
735                           table, TRUE, TRUE, 0);
736
737       darea = gtk_drawing_area_new ();
738
739       hadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
740       g_signal_connect (hadj, "value_changed",
741                         G_CALLBACK (pattern_hadj_changed), darea);
742       g_object_set_data (G_OBJECT (hadj), "old-value", &current_x);
743       
744       vadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
745       g_signal_connect (vadj, "value_changed",
746                         G_CALLBACK (pattern_vadj_changed), darea);
747       g_object_set_data (G_OBJECT (vadj), "old-value", &current_y);
748       
749       g_signal_connect (darea, "realize",
750                         G_CALLBACK (pattern_realize),
751                         NULL);
752       g_signal_connect (darea, "expose_event",
753                         G_CALLBACK (pattern_expose),
754                         NULL);
755
756       eventbox = gtk_event_box_new ();
757       gtk_table_attach (GTK_TABLE (table), eventbox,
758                         0, 1,                  0, 1,
759                         GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
760                         0,                     0);
761
762       gtk_container_add (GTK_CONTAINER (eventbox), darea);
763
764       scrollbar = gtk_hscrollbar_new (hadj);
765       gtk_table_attach (GTK_TABLE (table), scrollbar,
766                         0, 1,                  1, 2,
767                         GTK_FILL | GTK_EXPAND, GTK_FILL,
768                         0,                     0);
769
770       scrollbar = gtk_vscrollbar_new (vadj);
771       gtk_table_attach (GTK_TABLE (table), scrollbar,
772                         1, 2,                  0, 1,
773                         GTK_FILL,              GTK_EXPAND | GTK_FILL,
774                         0,                     0);
775
776     }
777
778   if (!GTK_WIDGET_VISIBLE (window))
779     gtk_widget_show_all (window);
780   else
781     gtk_widget_hide (window);
782 }
783
784 /*
785  * GtkButton
786  */
787
788 static void
789 button_window (GtkWidget *widget,
790                GtkWidget *button)
791 {
792   if (!GTK_WIDGET_VISIBLE (button))
793     gtk_widget_show (button);
794   else
795     gtk_widget_hide (button);
796 }
797
798 static void
799 create_buttons (GtkWidget *widget)
800 {
801   static GtkWidget *window = NULL;
802   GtkWidget *box1;
803   GtkWidget *box2;
804   GtkWidget *table;
805   GtkWidget *button[10];
806   GtkWidget *separator;
807
808   if (!window)
809     {
810       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
811       gtk_window_set_screen (GTK_WINDOW (window),
812                              gtk_widget_get_screen (widget));
813
814       g_signal_connect (window, "destroy",
815                         G_CALLBACK (gtk_widget_destroyed),
816                         &window);
817
818       gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
819       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
820
821       box1 = gtk_vbox_new (FALSE, 0);
822       gtk_container_add (GTK_CONTAINER (window), box1);
823
824       table = gtk_table_new (3, 3, FALSE);
825       gtk_table_set_row_spacings (GTK_TABLE (table), 5);
826       gtk_table_set_col_spacings (GTK_TABLE (table), 5);
827       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
828       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
829
830       button[0] = gtk_button_new_with_label ("button1");
831       button[1] = gtk_button_new_with_mnemonic ("_button2");
832       button[2] = gtk_button_new_with_mnemonic ("_button3");
833       button[3] = gtk_button_new_from_stock (GTK_STOCK_OK);
834       button[4] = gtk_button_new_with_label ("button5");
835       button[5] = gtk_button_new_with_label ("button6");
836       button[6] = gtk_button_new_with_label ("button7");
837       button[7] = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
838       button[8] = gtk_button_new_with_label ("button9");
839       
840       g_signal_connect (button[0], "clicked",
841                         G_CALLBACK (button_window),
842                         button[1]);
843
844       gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
845                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
846
847       g_signal_connect (button[1], "clicked",
848                         G_CALLBACK (button_window),
849                         button[2]);
850
851       gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
852                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
853
854       g_signal_connect (button[2], "clicked",
855                         G_CALLBACK (button_window),
856                         button[3]);
857       gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
858                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
859
860       g_signal_connect (button[3], "clicked",
861                         G_CALLBACK (button_window),
862                         button[4]);
863       gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
864                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
865
866       g_signal_connect (button[4], "clicked",
867                         G_CALLBACK (button_window),
868                         button[5]);
869       gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
870                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
871
872       g_signal_connect (button[5], "clicked",
873                         G_CALLBACK (button_window),
874                         button[6]);
875       gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
876                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
877
878       g_signal_connect (button[6], "clicked",
879                         G_CALLBACK (button_window),
880                         button[7]);
881       gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
882                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
883
884       g_signal_connect (button[7], "clicked",
885                         G_CALLBACK (button_window),
886                         button[8]);
887       gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
888                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
889
890       g_signal_connect (button[8], "clicked",
891                         G_CALLBACK (button_window),
892                         button[0]);
893       gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
894                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
895
896       separator = gtk_hseparator_new ();
897       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
898
899       box2 = gtk_vbox_new (FALSE, 10);
900       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
901       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
902
903       button[9] = gtk_button_new_with_label ("close");
904       g_signal_connect_swapped (button[9], "clicked",
905                                 G_CALLBACK (gtk_widget_destroy),
906                                 window);
907       gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
908       GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
909       gtk_widget_grab_default (button[9]);
910     }
911
912   if (!GTK_WIDGET_VISIBLE (window))
913     gtk_widget_show_all (window);
914   else
915     gtk_widget_destroy (window);
916 }
917
918 /*
919  * GtkToggleButton
920  */
921
922 static void
923 create_toggle_buttons (GtkWidget *widget)
924 {
925   static GtkWidget *window = NULL;
926   GtkWidget *box1;
927   GtkWidget *box2;
928   GtkWidget *button;
929   GtkWidget *separator;
930
931   if (!window)
932     {
933       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
934       gtk_window_set_screen (GTK_WINDOW (window),
935                              gtk_widget_get_screen (widget));
936
937       g_signal_connect (window, "destroy",
938                         G_CALLBACK (gtk_widget_destroyed),
939                         &window);
940
941       gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
942       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
943
944       box1 = gtk_vbox_new (FALSE, 0);
945       gtk_container_add (GTK_CONTAINER (window), box1);
946
947       box2 = gtk_vbox_new (FALSE, 10);
948       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
949       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
950
951       button = gtk_toggle_button_new_with_label ("button1");
952       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
953
954       button = gtk_toggle_button_new_with_label ("button2");
955       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
956
957       button = gtk_toggle_button_new_with_label ("button3");
958       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
959
960       button = gtk_toggle_button_new_with_label ("inconsistent");
961       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
962       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
963       
964       separator = gtk_hseparator_new ();
965       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
966
967       box2 = gtk_vbox_new (FALSE, 10);
968       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
969       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
970
971       button = gtk_button_new_with_label ("close");
972       g_signal_connect_swapped (button, "clicked",
973                                 G_CALLBACK (gtk_widget_destroy),
974                                 window);
975       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
976       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
977       gtk_widget_grab_default (button);
978     }
979
980   if (!GTK_WIDGET_VISIBLE (window))
981     gtk_widget_show_all (window);
982   else
983     gtk_widget_destroy (window);
984 }
985
986 static GtkWidget *
987 create_widget_grid (GType widget_type)
988 {
989   GtkWidget *table;
990   GtkWidget *group_widget = NULL;
991   gint i, j;
992   
993   table = gtk_table_new (FALSE, 3, 3);
994   
995   for (i = 0; i < 5; i++)
996     {
997       for (j = 0; j < 5; j++)
998         {
999           GtkWidget *widget;
1000           char *tmp;
1001           
1002           if (i == 0 && j == 0)
1003             {
1004               widget = NULL;
1005             }
1006           else if (i == 0)
1007             {
1008               tmp = g_strdup_printf ("%d", j);
1009               widget = gtk_label_new (tmp);
1010               g_free (tmp);
1011             }
1012           else if (j == 0)
1013             {
1014               tmp = g_strdup_printf ("%c", 'A' + i - 1);
1015               widget = gtk_label_new (tmp);
1016               g_free (tmp);
1017             }
1018           else
1019             {
1020               widget = g_object_new (widget_type, NULL);
1021               
1022               if (g_type_is_a (widget_type, GTK_TYPE_RADIO_BUTTON))
1023                 {
1024                   if (!group_widget)
1025                     group_widget = widget;
1026                   else
1027                     g_object_set (widget, "group", group_widget, NULL);
1028                 }
1029             }
1030           
1031           if (widget)
1032             gtk_table_attach (GTK_TABLE (table), widget,
1033                               i, i + 1, j, j + 1,
1034                               0,        0,
1035                               0,        0);
1036         }
1037     }
1038
1039   return table;
1040 }
1041
1042 /*
1043  * GtkCheckButton
1044  */
1045
1046 static void
1047 create_check_buttons (GtkWidget *widget)
1048 {
1049   static GtkWidget *window = NULL;
1050   GtkWidget *box1;
1051   GtkWidget *box2;
1052   GtkWidget *button;
1053   GtkWidget *separator;
1054   GtkWidget *table;
1055   
1056   if (!window)
1057     {
1058       window = gtk_dialog_new_with_buttons ("Check Buttons",
1059                                             NULL, 0,
1060                                             GTK_STOCK_CLOSE,
1061                                             GTK_RESPONSE_NONE,
1062                                             NULL);
1063
1064       gtk_window_set_screen (GTK_WINDOW (window), 
1065                              gtk_widget_get_screen (widget));
1066
1067       g_signal_connect (window, "destroy",
1068                         G_CALLBACK (gtk_widget_destroyed),
1069                         &window);
1070       g_signal_connect (window, "response",
1071                         G_CALLBACK (gtk_widget_destroy),
1072                         NULL);
1073
1074       box1 = GTK_DIALOG (window)->vbox;
1075       
1076       box2 = gtk_vbox_new (FALSE, 10);
1077       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1078       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1079
1080       button = gtk_check_button_new_with_mnemonic ("_button1");
1081       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1082
1083       button = gtk_check_button_new_with_label ("button2");
1084       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1085
1086       button = gtk_check_button_new_with_label ("button3");
1087       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1088
1089       button = gtk_check_button_new_with_label ("inconsistent");
1090       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
1091       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1092
1093       separator = gtk_hseparator_new ();
1094       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1095
1096       table = create_widget_grid (GTK_TYPE_CHECK_BUTTON);
1097       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
1098       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
1099     }
1100
1101   if (!GTK_WIDGET_VISIBLE (window))
1102     gtk_widget_show_all (window);
1103   else
1104     gtk_widget_destroy (window);
1105 }
1106
1107 /*
1108  * GtkRadioButton
1109  */
1110
1111 static void
1112 create_radio_buttons (GtkWidget *widget)
1113 {
1114   static GtkWidget *window = NULL;
1115   GtkWidget *box1;
1116   GtkWidget *box2;
1117   GtkWidget *button;
1118   GtkWidget *separator;
1119   GtkWidget *table;
1120
1121   if (!window)
1122     {
1123       window = gtk_dialog_new_with_buttons ("Radio Buttons",
1124                                             NULL, 0,
1125                                             GTK_STOCK_CLOSE,
1126                                             GTK_RESPONSE_NONE,
1127                                             NULL);
1128
1129       gtk_window_set_screen (GTK_WINDOW (window),
1130                              gtk_widget_get_screen (widget));
1131
1132       g_signal_connect (window, "destroy",
1133                         G_CALLBACK (gtk_widget_destroyed),
1134                         &window);
1135       g_signal_connect (window, "response",
1136                         G_CALLBACK (gtk_widget_destroy),
1137                         NULL);
1138
1139       box1 = GTK_DIALOG (window)->vbox;
1140
1141       box2 = gtk_vbox_new (FALSE, 10);
1142       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1143       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1144
1145       button = gtk_radio_button_new_with_label (NULL, "button1");
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                  "button2");
1151       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1152       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1153
1154       button = gtk_radio_button_new_with_label (
1155                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1156                  "button3");
1157       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1158
1159       button = gtk_radio_button_new_with_label (
1160                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1161                  "inconsistent");
1162       gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
1163       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1164       
1165       separator = gtk_hseparator_new ();
1166       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1167
1168       box2 = gtk_vbox_new (FALSE, 10);
1169       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1170       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1171
1172       button = gtk_radio_button_new_with_label (NULL, "button4");
1173       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1174       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1175
1176       button = gtk_radio_button_new_with_label (
1177                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1178                  "button5");
1179       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
1180       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1181       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1182
1183       button = gtk_radio_button_new_with_label (
1184                  gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
1185                  "button6");
1186       gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
1187       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1188
1189       separator = gtk_hseparator_new ();
1190       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1191
1192       table = create_widget_grid (GTK_TYPE_RADIO_BUTTON);
1193       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
1194       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
1195     }
1196
1197   if (!GTK_WIDGET_VISIBLE (window))
1198     gtk_widget_show_all (window);
1199   else
1200     gtk_widget_destroy (window);
1201 }
1202
1203 /*
1204  * GtkButtonBox
1205  */
1206
1207 static GtkWidget *
1208 create_bbox (gint  horizontal,
1209              char* title, 
1210              gint  spacing,
1211              gint  child_w,
1212              gint  child_h,
1213              gint  layout)
1214 {
1215   GtkWidget *frame;
1216   GtkWidget *bbox;
1217   GtkWidget *button;
1218         
1219   frame = gtk_frame_new (title);
1220
1221   if (horizontal)
1222     bbox = gtk_hbutton_box_new ();
1223   else
1224     bbox = gtk_vbutton_box_new ();
1225
1226   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
1227   gtk_container_add (GTK_CONTAINER (frame), bbox);
1228
1229   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
1230   gtk_box_set_spacing (GTK_BOX (bbox), spacing);
1231   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
1232   
1233   button = gtk_button_new_with_label ("OK");
1234   gtk_container_add (GTK_CONTAINER (bbox), button);
1235   
1236   button = gtk_button_new_with_label ("Cancel");
1237   gtk_container_add (GTK_CONTAINER (bbox), button);
1238   
1239   button = gtk_button_new_with_label ("Help");
1240   gtk_container_add (GTK_CONTAINER (bbox), button);
1241
1242   return frame;
1243 }
1244
1245 static void
1246 create_button_box (GtkWidget *widget)
1247 {
1248   static GtkWidget* window = NULL;
1249   GtkWidget *main_vbox;
1250   GtkWidget *vbox;
1251   GtkWidget *hbox;
1252   GtkWidget *frame_horz;
1253   GtkWidget *frame_vert;
1254
1255   if (!window)
1256   {
1257     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1258     gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget));
1259     gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
1260     
1261     g_signal_connect (window, "destroy",
1262                       G_CALLBACK (gtk_widget_destroyed),
1263                       &window);
1264     
1265     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
1266
1267     main_vbox = gtk_vbox_new (FALSE, 0);
1268     gtk_container_add (GTK_CONTAINER (window), main_vbox);
1269     
1270     frame_horz = gtk_frame_new ("Horizontal Button Boxes");
1271     gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
1272     
1273     vbox = gtk_vbox_new (FALSE, 0);
1274     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
1275     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
1276     
1277     gtk_box_pack_start (GTK_BOX (vbox), 
1278                         create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
1279                         TRUE, TRUE, 0);
1280     
1281     gtk_box_pack_start (GTK_BOX (vbox), 
1282                         create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
1283                         TRUE, TRUE, 5);
1284     
1285     gtk_box_pack_start (GTK_BOX (vbox), 
1286                         create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
1287                         TRUE, TRUE, 5);
1288     
1289     gtk_box_pack_start (GTK_BOX (vbox), 
1290                         create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
1291                         TRUE, TRUE, 5);
1292     
1293     gtk_box_pack_start (GTK_BOX (vbox),
1294                         create_bbox (TRUE, "Center", 40, 85, 20, GTK_BUTTONBOX_CENTER),
1295                         TRUE, TRUE, 5);
1296     
1297     frame_vert = gtk_frame_new ("Vertical Button Boxes");
1298     gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
1299     
1300     hbox = gtk_hbox_new (FALSE, 0);
1301     gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1302     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
1303
1304     gtk_box_pack_start (GTK_BOX (hbox), 
1305                         create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
1306                         TRUE, TRUE, 0);
1307     
1308     gtk_box_pack_start (GTK_BOX (hbox), 
1309                         create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
1310                         TRUE, TRUE, 5);
1311     
1312     gtk_box_pack_start (GTK_BOX (hbox), 
1313                         create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
1314                         TRUE, TRUE, 5);
1315     
1316     gtk_box_pack_start (GTK_BOX (hbox), 
1317                         create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
1318                         TRUE, TRUE, 5);
1319     
1320     gtk_box_pack_start (GTK_BOX (hbox),
1321                         create_bbox (FALSE, "Center", 30, 85, 20, GTK_BUTTONBOX_CENTER),
1322                         TRUE, TRUE, 5);
1323   }
1324
1325   if (!GTK_WIDGET_VISIBLE (window))
1326     gtk_widget_show_all (window);
1327   else
1328     gtk_widget_destroy (window);
1329 }
1330
1331 /*
1332  * GtkToolBar
1333  */
1334
1335 static GtkWidget*
1336 new_pixmap (char      *filename,
1337             GdkWindow *window,
1338             GdkColor  *background)
1339 {
1340   GtkWidget *wpixmap;
1341   GdkPixmap *pixmap;
1342   GdkBitmap *mask;
1343
1344   if (strcmp (filename, "test.xpm") == 0 ||
1345       !file_exists (filename))
1346     {
1347       pixmap = gdk_pixmap_create_from_xpm_d (window, &mask,
1348                                              background,
1349                                              openfile);
1350     }
1351   else
1352     pixmap = gdk_pixmap_create_from_xpm (window, &mask,
1353                                          background,
1354                                          filename);
1355   
1356   wpixmap = gtk_image_new_from_pixmap (pixmap, mask);
1357
1358   return wpixmap;
1359 }
1360
1361
1362 static void
1363 set_toolbar_small_stock (GtkWidget *widget,
1364                          gpointer   data)
1365 {
1366   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_SMALL_TOOLBAR);
1367 }
1368
1369 static void
1370 set_toolbar_large_stock (GtkWidget *widget,
1371                          gpointer   data)
1372 {
1373   gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_LARGE_TOOLBAR);
1374 }
1375
1376 static void
1377 set_toolbar_horizontal (GtkWidget *widget,
1378                         gpointer   data)
1379 {
1380   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_HORIZONTAL);
1381 }
1382
1383 static void
1384 set_toolbar_vertical (GtkWidget *widget,
1385                       gpointer   data)
1386 {
1387   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_VERTICAL);
1388 }
1389
1390 static void
1391 set_toolbar_icons (GtkWidget *widget,
1392                    gpointer   data)
1393 {
1394   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
1395 }
1396
1397 static void
1398 set_toolbar_text (GtkWidget *widget,
1399                   gpointer   data)
1400 {
1401   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
1402 }
1403
1404 static void
1405 set_toolbar_both (GtkWidget *widget,
1406                   gpointer   data)
1407 {
1408   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
1409 }
1410
1411 static void
1412 set_toolbar_both_horiz (GtkWidget *widget,
1413                         gpointer   data)
1414 {
1415   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH_HORIZ);
1416 }
1417
1418 static void
1419 set_toolbar_enable (GtkWidget *widget,
1420                     gpointer   data)
1421 {
1422   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), TRUE);
1423 }
1424
1425 static void
1426 set_toolbar_disable (GtkWidget *widget,
1427                      gpointer   data)
1428 {
1429   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), FALSE);
1430 }
1431
1432 static void
1433 create_toolbar (GtkWidget *widget)
1434 {
1435   static GtkWidget *window = NULL;
1436   GtkWidget *toolbar;
1437   GtkWidget *entry;
1438
1439   if (!window)
1440     {
1441       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1442       gtk_window_set_screen (GTK_WINDOW (window),
1443                              gtk_widget_get_screen (widget));
1444       
1445       gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
1446
1447       g_signal_connect (window, "destroy",
1448                         G_CALLBACK (gtk_widget_destroyed),
1449                         &window);
1450
1451       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1452       gtk_widget_realize (window);
1453
1454       toolbar = gtk_toolbar_new ();
1455
1456       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
1457                                 GTK_STOCK_NEW,
1458                                 "Stock icon: New", "Toolbar/New",
1459                                 G_CALLBACK (set_toolbar_small_stock), toolbar, -1);
1460       
1461       gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
1462                                 GTK_STOCK_OPEN,
1463                                 "Stock icon: Open", "Toolbar/Open",
1464                                 G_CALLBACK (set_toolbar_large_stock), toolbar, -1);
1465       
1466       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1467                                "Horizontal", "Horizontal toolbar layout", "Toolbar/Horizontal",
1468                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1469                                G_CALLBACK (set_toolbar_horizontal), toolbar);
1470       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1471                                "Vertical", "Vertical toolbar layout", "Toolbar/Vertical",
1472                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1473                                G_CALLBACK (set_toolbar_vertical), toolbar);
1474
1475       gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
1476
1477       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1478                                "Icons", "Only show toolbar icons", "Toolbar/IconsOnly",
1479                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1480                                G_CALLBACK (set_toolbar_icons), toolbar);
1481       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1482                                "Text", "Only show toolbar text", "Toolbar/TextOnly",
1483                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1484                                G_CALLBACK (set_toolbar_text), toolbar);
1485       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1486                                "Both", "Show toolbar icons and text", "Toolbar/Both",
1487                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1488                                G_CALLBACK (set_toolbar_both), toolbar);
1489       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1490                                "Both (horizontal)",
1491                                "Show toolbar icons and text in a horizontal fashion",
1492                                "Toolbar/BothHoriz",
1493                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1494                                G_CALLBACK (set_toolbar_both_horiz), toolbar);
1495                                
1496       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1497
1498       entry = gtk_entry_new ();
1499
1500       gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), entry, "This is an unusable GtkEntry ;)", "Hey don't click me!!!");
1501
1502       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1503
1504
1505       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1506
1507       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1508                                "Enable", "Enable tooltips", NULL,
1509                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1510                                G_CALLBACK (set_toolbar_enable), toolbar);
1511       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1512                                "Disable", "Disable tooltips", NULL,
1513                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1514                                G_CALLBACK (set_toolbar_disable), toolbar);
1515
1516       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1517
1518       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1519                                "Frobate", "Frobate tooltip", NULL,
1520                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1521                                NULL, toolbar);
1522       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1523                                "Baz", "Baz tooltip", NULL,
1524                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1525                                NULL, toolbar);
1526
1527       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1528       
1529       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1530                                "Blah", "Blah tooltip", NULL,
1531                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1532                                NULL, toolbar);
1533       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1534                                "Bar", "Bar tooltip", NULL,
1535                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1536                                NULL, toolbar);
1537
1538       gtk_container_add (GTK_CONTAINER (window), toolbar);
1539
1540       gtk_widget_set_size_request (toolbar, 200, -1);
1541     }
1542
1543   if (!GTK_WIDGET_VISIBLE (window))
1544     gtk_widget_show_all (window);
1545   else
1546     gtk_widget_destroy (window);
1547 }
1548
1549 static GtkWidget*
1550 make_toolbar (GtkWidget *window)
1551 {
1552   GtkWidget *toolbar;
1553
1554   if (!GTK_WIDGET_REALIZED (window))
1555     gtk_widget_realize (window);
1556
1557   toolbar = gtk_toolbar_new ();
1558
1559   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1560                            "Horizontal", "Horizontal toolbar layout", NULL,
1561                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1562                            G_CALLBACK (set_toolbar_horizontal), toolbar);
1563   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1564                            "Vertical", "Vertical toolbar layout", NULL,
1565                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1566                            G_CALLBACK (set_toolbar_vertical), toolbar);
1567
1568   gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
1569
1570   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1571                            "Icons", "Only show toolbar icons", NULL,
1572                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1573                            G_CALLBACK (set_toolbar_icons), toolbar);
1574   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1575                            "Text", "Only show toolbar text", NULL,
1576                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1577                            G_CALLBACK (set_toolbar_text), toolbar);
1578   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1579                            "Both", "Show toolbar icons and text", NULL,
1580                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1581                            G_CALLBACK (set_toolbar_both), toolbar);
1582
1583   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1584
1585   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1586                            "Woot", "Woot woot woot", NULL,
1587                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1588                            NULL, toolbar);
1589   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1590                            "Blah", "Blah blah blah", "Toolbar/Big",
1591                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1592                            NULL, toolbar);
1593
1594   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1595
1596   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1597                            "Enable", "Enable tooltips", NULL,
1598                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1599                            G_CALLBACK (set_toolbar_enable), toolbar);
1600   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1601                            "Disable", "Disable tooltips", NULL,
1602                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1603                            G_CALLBACK (set_toolbar_disable), toolbar);
1604
1605   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1606   
1607   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1608                            "Hoo", "Hoo tooltip", NULL,
1609                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1610                            NULL, toolbar);
1611   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1612                            "Woo", "Woo tooltip", NULL,
1613                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
1614                            NULL, toolbar);
1615
1616   return toolbar;
1617 }
1618
1619 /*
1620  * GtkStatusBar
1621  */
1622
1623 static guint statusbar_counter = 1;
1624
1625 static void
1626 statusbar_push (GtkWidget *button,
1627                 GtkStatusbar *statusbar)
1628 {
1629   gchar text[1024];
1630
1631   sprintf (text, "something %d", statusbar_counter++);
1632
1633   gtk_statusbar_push (statusbar, 1, text);
1634 }
1635
1636 static void
1637 statusbar_push_long (GtkWidget *button,
1638                      GtkStatusbar *statusbar)
1639 {
1640   gchar text[1024];
1641
1642   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\").");
1643
1644   gtk_statusbar_push (statusbar, 1, text);
1645 }
1646
1647 static void
1648 statusbar_pop (GtkWidget *button,
1649                GtkStatusbar *statusbar)
1650 {
1651   gtk_statusbar_pop (statusbar, 1);
1652 }
1653
1654 static void
1655 statusbar_steal (GtkWidget *button,
1656                  GtkStatusbar *statusbar)
1657 {
1658   gtk_statusbar_remove (statusbar, 1, 4);
1659 }
1660
1661 static void
1662 statusbar_popped (GtkStatusbar  *statusbar,
1663                   guint          context_id,
1664                   const gchar   *text)
1665 {
1666   if (!statusbar->messages)
1667     statusbar_counter = 1;
1668 }
1669
1670 static void
1671 statusbar_contexts (GtkStatusbar *statusbar)
1672 {
1673   gchar *string;
1674
1675   string = "any context";
1676   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1677            string,
1678            gtk_statusbar_get_context_id (statusbar, string));
1679   
1680   string = "idle messages";
1681   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1682            string,
1683            gtk_statusbar_get_context_id (statusbar, string));
1684   
1685   string = "some text";
1686   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1687            string,
1688            gtk_statusbar_get_context_id (statusbar, string));
1689
1690   string = "hit the mouse";
1691   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1692            string,
1693            gtk_statusbar_get_context_id (statusbar, string));
1694
1695   string = "hit the mouse2";
1696   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1697            string,
1698            gtk_statusbar_get_context_id (statusbar, string));
1699 }
1700
1701 static void
1702 create_statusbar (GtkWidget *widget)
1703 {
1704   static GtkWidget *window = NULL;
1705   GtkWidget *box1;
1706   GtkWidget *box2;
1707   GtkWidget *button;
1708   GtkWidget *separator;
1709   GtkWidget *statusbar;
1710
1711   if (!window)
1712     {
1713       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1714       gtk_window_set_screen (GTK_WINDOW (window),
1715                              gtk_widget_get_screen (widget));
1716
1717       g_signal_connect (window, "destroy",
1718                         G_CALLBACK (gtk_widget_destroyed),
1719                         &window);
1720
1721       gtk_window_set_title (GTK_WINDOW (window), "statusbar");
1722       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1723
1724       box1 = gtk_vbox_new (FALSE, 0);
1725       gtk_container_add (GTK_CONTAINER (window), box1);
1726
1727       box2 = gtk_vbox_new (FALSE, 10);
1728       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1729       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1730
1731       statusbar = gtk_statusbar_new ();
1732       gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
1733       g_signal_connect (statusbar,
1734                         "text_popped",
1735                         G_CALLBACK (statusbar_popped),
1736                         NULL);
1737
1738       button = gtk_widget_new (gtk_button_get_type (),
1739                                "label", "push something",
1740                                "visible", TRUE,
1741                                "parent", box2,
1742                                NULL);
1743       g_object_connect (button,
1744                         "signal::clicked", statusbar_push, statusbar,
1745                         NULL);
1746
1747       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1748                                                  "label", "pop",
1749                                                  "visible", TRUE,
1750                                                  "parent", box2,
1751                                                  NULL),
1752                                  "signal_after::clicked", statusbar_pop, statusbar,
1753                                  NULL);
1754
1755       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1756                                                  "label", "steal #4",
1757                                                  "visible", TRUE,
1758                                                  "parent", box2,
1759                                                  NULL),
1760                                  "signal_after::clicked", statusbar_steal, statusbar,
1761                                  NULL);
1762
1763       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1764                                                  "label", "test contexts",
1765                                                  "visible", TRUE,
1766                                                  "parent", box2,
1767                                                  NULL),
1768                                  "swapped_signal_after::clicked", statusbar_contexts, statusbar,
1769                                  NULL);
1770
1771       button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
1772                                                  "label", "push something long",
1773                                                  "visible", TRUE,
1774                                                  "parent", box2,
1775                                                  NULL),
1776                                  "signal_after::clicked", statusbar_push_long, statusbar,
1777                                  NULL);
1778       
1779       separator = gtk_hseparator_new ();
1780       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1781
1782       box2 = gtk_vbox_new (FALSE, 10);
1783       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1784       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1785
1786       button = gtk_button_new_with_label ("close");
1787       g_signal_connect_swapped (button, "clicked",
1788                                 G_CALLBACK (gtk_widget_destroy),
1789                                 window);
1790       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1791       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1792       gtk_widget_grab_default (button);
1793     }
1794
1795   if (!GTK_WIDGET_VISIBLE (window))
1796     gtk_widget_show_all (window);
1797   else
1798     gtk_widget_destroy (window);
1799 }
1800
1801 /*
1802  * GtkTree
1803  */
1804
1805 static void
1806 cb_tree_destroy_event(GtkWidget* w)
1807 {
1808   sTreeButtons* tree_buttons;
1809
1810   /* free buttons structure associate at this tree */
1811   tree_buttons = g_object_get_data (G_OBJECT (w), "user_data");
1812   g_free (tree_buttons);
1813 }
1814
1815 static void
1816 cb_add_new_item(GtkWidget* w, GtkTree* tree)
1817 {
1818   sTreeButtons* tree_buttons;
1819   GList* selected_list;
1820   GtkWidget* selected_item;
1821   GtkWidget* subtree;
1822   GtkWidget* item_new;
1823   char buffer[255];
1824
1825   tree_buttons = g_object_get_data (G_OBJECT (tree), "user_data");
1826
1827   selected_list = GTK_TREE_SELECTION_OLD(tree);
1828
1829   if(selected_list == NULL)
1830     {
1831       /* there is no item in tree */
1832       subtree = GTK_WIDGET(tree);
1833     }
1834   else
1835     {
1836       /* list can have only one element */
1837       selected_item = GTK_WIDGET(selected_list->data);
1838       
1839       subtree = GTK_TREE_ITEM_SUBTREE(selected_item);
1840
1841       if(subtree == NULL)
1842         {
1843           /* current selected item have not subtree ... create it */
1844           subtree = gtk_tree_new();
1845           gtk_tree_item_set_subtree(GTK_TREE_ITEM(selected_item), 
1846                                     subtree);
1847         }
1848     }
1849
1850   /* at this point, we know which subtree will be used to add new item */
1851   /* create a new item */
1852   sprintf(buffer, "item add %d", tree_buttons->nb_item_add);
1853   item_new = gtk_tree_item_new_with_label(buffer);
1854   gtk_tree_append(GTK_TREE(subtree), item_new);
1855   gtk_widget_show(item_new);
1856
1857   tree_buttons->nb_item_add++;
1858 }
1859
1860 static void
1861 cb_remove_item(GtkWidget*w, GtkTree* tree)
1862 {
1863   GList* selected_list;
1864   GList* clear_list;
1865   
1866   selected_list = GTK_TREE_SELECTION_OLD(tree);
1867
1868   clear_list = NULL;
1869     
1870   while (selected_list) 
1871     {
1872       clear_list = g_list_prepend (clear_list, selected_list->data);
1873       selected_list = selected_list->next;
1874     }
1875   
1876   clear_list = g_list_reverse (clear_list);
1877   gtk_tree_remove_items(tree, clear_list);
1878
1879   g_list_free (clear_list);
1880 }
1881
1882 static void
1883 cb_remove_subtree(GtkWidget*w, GtkTree* tree)
1884 {
1885   GList* selected_list;
1886   GtkTreeItem *item;
1887   
1888   selected_list = GTK_TREE_SELECTION_OLD(tree);
1889
1890   if (selected_list)
1891     {
1892       item = GTK_TREE_ITEM (selected_list->data);
1893       if (item->subtree)
1894         gtk_tree_item_remove_subtree (item);
1895     }
1896 }
1897
1898 static void
1899 cb_tree_changed(GtkTree* tree)
1900 {
1901   sTreeButtons* tree_buttons;
1902   GList* selected_list;
1903   guint nb_selected;
1904
1905   tree_buttons = g_object_get_data (G_OBJECT (tree), "user_data");
1906
1907   selected_list = GTK_TREE_SELECTION_OLD(tree);
1908   nb_selected = g_list_length(selected_list);
1909
1910   if(nb_selected == 0) 
1911     {
1912       if(tree->children == NULL)
1913         gtk_widget_set_sensitive(tree_buttons->add_button, TRUE);
1914       else
1915         gtk_widget_set_sensitive(tree_buttons->add_button, FALSE);
1916       gtk_widget_set_sensitive(tree_buttons->remove_button, FALSE);
1917       gtk_widget_set_sensitive(tree_buttons->subtree_button, FALSE);
1918     } 
1919   else 
1920     {
1921       gtk_widget_set_sensitive(tree_buttons->remove_button, TRUE);
1922       gtk_widget_set_sensitive(tree_buttons->add_button, (nb_selected == 1));
1923       gtk_widget_set_sensitive(tree_buttons->subtree_button, (nb_selected == 1));
1924     }  
1925 }
1926
1927 static void 
1928 create_subtree(GtkWidget* item, guint level, guint nb_item_max, guint recursion_level_max)
1929 {
1930   GtkWidget* item_subtree;
1931   GtkWidget* item_new;
1932   guint nb_item;
1933   char buffer[255];
1934   int no_root_item;
1935
1936   if(level == recursion_level_max) return;
1937
1938   if(level == -1)
1939     {
1940       /* query with no root item */
1941       level = 0;
1942       item_subtree = item;
1943       no_root_item = 1;
1944     }
1945   else
1946     {
1947       /* query with no root item */
1948       /* create subtree and associate it with current item */
1949       item_subtree = gtk_tree_new();
1950       no_root_item = 0;
1951     }
1952   
1953   for(nb_item = 0; nb_item < nb_item_max; nb_item++)
1954     {
1955       sprintf(buffer, "item %d-%d", level, nb_item);
1956       item_new = gtk_tree_item_new_with_label(buffer);
1957       gtk_tree_append(GTK_TREE(item_subtree), item_new);
1958       create_subtree(item_new, level+1, nb_item_max, recursion_level_max);
1959       gtk_widget_show(item_new);
1960     }
1961
1962   if(!no_root_item)
1963     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), item_subtree);
1964 }
1965
1966 static void
1967 create_tree_sample(GdkScreen *screen, guint selection_mode, 
1968                    guint draw_line, guint view_line, guint no_root_item,
1969                    guint nb_item_max, guint recursion_level_max) 
1970 {
1971   GtkWidget* window;
1972   GtkWidget* box1;
1973   GtkWidget* box2;
1974   GtkWidget* separator;
1975   GtkWidget* button;
1976   GtkWidget* scrolled_win;
1977   GtkWidget* root_tree;
1978   GtkWidget* root_item;
1979   sTreeButtons* tree_buttons;
1980
1981   /* create tree buttons struct */
1982   if ((tree_buttons = g_malloc (sizeof (sTreeButtons))) == NULL)
1983     {
1984       g_error("can't allocate memory for tree structure !\n");
1985       return;
1986     }
1987   tree_buttons->nb_item_add = 0;
1988
1989   /* create top level window */
1990   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1991   gtk_window_set_screen (GTK_WINDOW (window), screen);
1992   gtk_window_set_title(GTK_WINDOW(window), "Tree Sample");
1993   g_signal_connect (window, "destroy",
1994                     G_CALLBACK (cb_tree_destroy_event), NULL);
1995   g_object_set_data (G_OBJECT (window), "user_data", tree_buttons);
1996
1997   box1 = gtk_vbox_new(FALSE, 0);
1998   gtk_container_add(GTK_CONTAINER(window), box1);
1999   gtk_widget_show(box1);
2000
2001   /* create tree box */
2002   box2 = gtk_vbox_new(FALSE, 0);
2003   gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
2004   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
2005   gtk_widget_show(box2);
2006
2007   /* create scrolled window */
2008   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
2009   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
2010                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2011   gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
2012   gtk_widget_set_size_request (scrolled_win, 200, 200);
2013   gtk_widget_show (scrolled_win);
2014   
2015   /* create root tree widget */
2016   root_tree = gtk_tree_new();
2017   g_signal_connect (root_tree, "selection_changed",
2018                     G_CALLBACK (cb_tree_changed),
2019                     NULL);
2020   g_object_set_data (G_OBJECT (root_tree), "user_data", tree_buttons);
2021   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), root_tree);
2022   gtk_tree_set_selection_mode(GTK_TREE(root_tree), selection_mode);
2023   gtk_tree_set_view_lines(GTK_TREE(root_tree), draw_line);
2024   gtk_tree_set_view_mode(GTK_TREE(root_tree), !view_line);
2025   gtk_widget_show(root_tree);
2026
2027   if ( no_root_item )
2028     {
2029       /* set root tree to subtree function with root item variable */
2030       root_item = GTK_WIDGET(root_tree);
2031     }
2032   else
2033     {
2034       /* create root tree item widget */
2035       root_item = gtk_tree_item_new_with_label("root item");
2036       gtk_tree_append(GTK_TREE(root_tree), root_item);
2037       gtk_widget_show(root_item);
2038      }
2039   create_subtree(root_item, -no_root_item, nb_item_max, recursion_level_max);
2040
2041   box2 = gtk_vbox_new(FALSE, 0);
2042   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
2043   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
2044   gtk_widget_show(box2);
2045
2046   button = gtk_button_new_with_label("Add Item");
2047   gtk_widget_set_sensitive(button, FALSE);
2048   g_signal_connect (button, "clicked",
2049                     G_CALLBACK (cb_add_new_item),
2050                     root_tree);
2051   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2052   gtk_widget_show(button);
2053   tree_buttons->add_button = button;
2054
2055   button = gtk_button_new_with_label("Remove Item(s)");
2056   gtk_widget_set_sensitive(button, FALSE);
2057   g_signal_connect (button, "clicked",
2058                     G_CALLBACK (cb_remove_item),
2059                     root_tree);
2060   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2061   gtk_widget_show(button);
2062   tree_buttons->remove_button = button;
2063
2064   button = gtk_button_new_with_label("Remove Subtree");
2065   gtk_widget_set_sensitive(button, FALSE);
2066   g_signal_connect (button, "clicked",
2067                     G_CALLBACK (cb_remove_subtree),
2068                     root_tree);
2069   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2070   gtk_widget_show(button);
2071   tree_buttons->subtree_button = button;
2072
2073   /* create separator */
2074   separator = gtk_hseparator_new();
2075   gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
2076   gtk_widget_show(separator);
2077
2078   /* create button box */
2079   box2 = gtk_vbox_new(FALSE, 0);
2080   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
2081   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
2082   gtk_widget_show(box2);
2083
2084   button = gtk_button_new_with_label("Close");
2085   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2086   g_signal_connect_swapped (button, "clicked",
2087                             G_CALLBACK (gtk_widget_destroy),
2088                             window);
2089   gtk_widget_show(button);
2090
2091   gtk_widget_show(window);
2092 }
2093
2094 static void
2095 cb_create_tree(GtkWidget* w)
2096 {
2097   guint selection_mode = GTK_SELECTION_SINGLE;
2098   guint view_line;
2099   guint draw_line;
2100   guint no_root_item;
2101   guint nb_item;
2102   guint recursion_level;
2103
2104   /* get selection mode choice */
2105   if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.single_button)->active)
2106     selection_mode = GTK_SELECTION_SINGLE;
2107   else
2108     if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.browse_button)->active)
2109       selection_mode = GTK_SELECTION_BROWSE;
2110     else
2111       selection_mode = GTK_SELECTION_MULTIPLE;
2112
2113   /* get options choice */
2114   draw_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.draw_line_button)->active;
2115   view_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.view_line_button)->active;
2116   no_root_item = GTK_TOGGLE_BUTTON(sTreeSampleSelection.no_root_item_button)->active;
2117     
2118   /* get levels */
2119   nb_item = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.nb_item_spinner));
2120   recursion_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.recursion_spinner));
2121
2122   if (pow (nb_item, recursion_level) > 10000)
2123     {
2124       g_print ("%g total items? That will take a very long time. Try less\n",
2125                pow (nb_item, recursion_level));
2126       return;
2127     }
2128
2129   create_tree_sample(gtk_widget_get_screen (w),
2130                      selection_mode, draw_line, 
2131                      view_line, no_root_item, nb_item, recursion_level);
2132 }
2133
2134 void 
2135 create_tree_mode_window(GtkWidget *widget)
2136 {
2137   static GtkWidget* window;
2138   GtkWidget* box1;
2139   GtkWidget* box2;
2140   GtkWidget* box3;
2141   GtkWidget* box4;
2142   GtkWidget* box5;
2143   GtkWidget* button;
2144   GtkWidget* frame;
2145   GtkWidget* separator;
2146   GtkWidget* label;
2147   GtkWidget* spinner;
2148   GtkAdjustment *adj;
2149
2150   if (!window)
2151     {
2152       /* create toplevel window  */
2153       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2154       gtk_window_set_screen (GTK_WINDOW (window),
2155                              gtk_widget_get_screen (widget));
2156       gtk_window_set_title(GTK_WINDOW(window), "Set Tree Parameters");
2157       g_signal_connect (window, "destroy",
2158                         G_CALLBACK (gtk_widget_destroyed),
2159                         &window);
2160       box1 = gtk_vbox_new(FALSE, 0);
2161       gtk_container_add(GTK_CONTAINER(window), box1);
2162
2163       /* create upper box - selection box */
2164       box2 = gtk_vbox_new(FALSE, 5);
2165       gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
2166       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
2167
2168       box3 = gtk_hbox_new(FALSE, 5);
2169       gtk_box_pack_start(GTK_BOX(box2), box3, TRUE, TRUE, 0);
2170
2171       /* create selection mode frame */
2172       frame = gtk_frame_new("Selection Mode");
2173       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
2174
2175       box4 = gtk_vbox_new(FALSE, 0);
2176       gtk_container_add(GTK_CONTAINER(frame), box4);
2177       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
2178
2179       /* create radio button */  
2180       button = gtk_radio_button_new_with_label(NULL, "SINGLE");
2181       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2182       sTreeSampleSelection.single_button = button;
2183
2184       button = gtk_radio_button_new_with_label(gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
2185                                                "BROWSE");
2186       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2187       sTreeSampleSelection.browse_button = button;
2188
2189       button = gtk_radio_button_new_with_label(gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
2190                                                "MULTIPLE");
2191       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2192       sTreeSampleSelection.multiple_button = button;
2193
2194       sTreeSampleSelection.selection_mode_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
2195
2196       /* create option mode frame */
2197       frame = gtk_frame_new("Options");
2198       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
2199
2200       box4 = gtk_vbox_new(FALSE, 0);
2201       gtk_container_add(GTK_CONTAINER(frame), box4);
2202       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
2203
2204       /* create check button */
2205       button = gtk_check_button_new_with_label("Draw line");
2206       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2207       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
2208       sTreeSampleSelection.draw_line_button = button;
2209   
2210       button = gtk_check_button_new_with_label("View Line mode");
2211       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2212       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
2213       sTreeSampleSelection.view_line_button = button;
2214   
2215       button = gtk_check_button_new_with_label("Without Root item");
2216       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
2217       sTreeSampleSelection.no_root_item_button = button;
2218
2219       /* create recursion parameter */
2220       frame = gtk_frame_new("Size Parameters");
2221       gtk_box_pack_start(GTK_BOX(box2), frame, TRUE, TRUE, 0);
2222
2223       box4 = gtk_hbox_new(FALSE, 5);
2224       gtk_container_add(GTK_CONTAINER(frame), box4);
2225       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
2226
2227       /* create number of item spin button */
2228       box5 = gtk_hbox_new(FALSE, 5);
2229       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
2230
2231       label = gtk_label_new("Number of items : ");
2232       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2233       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
2234
2235       adj = (GtkAdjustment *) gtk_adjustment_new (DEFAULT_NUMBER_OF_ITEM, 1.0, 255.0, 1.0,
2236                                                   5.0, 0.0);
2237       spinner = gtk_spin_button_new (adj, 0, 0);
2238       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
2239       sTreeSampleSelection.nb_item_spinner = spinner;
2240   
2241       /* create recursion level spin button */
2242       box5 = gtk_hbox_new(FALSE, 5);
2243       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
2244
2245       label = gtk_label_new("Depth : ");
2246       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
2247       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
2248
2249       adj = (GtkAdjustment *) gtk_adjustment_new (DEFAULT_RECURSION_LEVEL, 0.0, 255.0, 1.0,
2250                                                   5.0, 0.0);
2251       spinner = gtk_spin_button_new (adj, 0, 0);
2252       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
2253       sTreeSampleSelection.recursion_spinner = spinner;
2254   
2255       /* create horizontal separator */
2256       separator = gtk_hseparator_new();
2257       gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
2258
2259       /* create bottom button box */
2260       box2 = gtk_hbox_new(TRUE, 10);
2261       gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
2262       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
2263
2264       button = gtk_button_new_with_label("Create Tree");
2265       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2266       g_signal_connect (button, "clicked",
2267                         G_CALLBACK (cb_create_tree), NULL);
2268
2269       button = gtk_button_new_with_label("Close");
2270       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
2271       g_signal_connect_swapped (button, "clicked",
2272                                 G_CALLBACK (gtk_widget_destroy),
2273                                 window);
2274     }
2275   if (!GTK_WIDGET_VISIBLE (window))
2276     gtk_widget_show_all (window);
2277   else
2278     gtk_widget_destroy (window);
2279 }
2280
2281 /*
2282  * Gridded geometry
2283  */
2284 #define GRID_SIZE 20
2285 #define DEFAULT_GEOMETRY "10x10"
2286
2287 static gboolean
2288 gridded_geometry_expose (GtkWidget      *widget,
2289                          GdkEventExpose *event)
2290 {
2291   int i, j;
2292
2293   gdk_draw_rectangle (widget->window, widget->style->base_gc[widget->state], TRUE,
2294                       0, 0, widget->allocation.width, widget->allocation.height);
2295   
2296   for (i = 0 ; i * GRID_SIZE < widget->allocation.width; i++)
2297     for (j = 0 ; j * GRID_SIZE < widget->allocation.height; j++)
2298       {
2299         if ((i + j) % 2 == 0)
2300           gdk_draw_rectangle (widget->window, widget->style->text_gc[widget->state], TRUE,
2301                               i * GRID_SIZE, j * GRID_SIZE, GRID_SIZE, GRID_SIZE);
2302       }
2303
2304   return FALSE;
2305 }
2306
2307 static void
2308 gridded_geometry_subresponse (GtkDialog *dialog,
2309                               gint       response_id,
2310                               gchar     *geometry_string)
2311 {
2312   if (response_id == GTK_RESPONSE_NONE)
2313     {
2314       gtk_widget_destroy (GTK_WIDGET (dialog));
2315     }
2316   else
2317     {
2318       if (!gtk_window_parse_geometry (GTK_WINDOW (dialog), geometry_string))
2319         {
2320           g_print ("Can't parse geometry string %s\n", geometry_string);
2321           gtk_window_parse_geometry (GTK_WINDOW (dialog), DEFAULT_GEOMETRY);
2322         }
2323     }
2324 }
2325
2326 static void
2327 gridded_geometry_response (GtkDialog *dialog,
2328                            gint       response_id,
2329                            GtkEntry  *entry)
2330 {
2331   if (response_id == GTK_RESPONSE_NONE)
2332     {
2333       gtk_widget_destroy (GTK_WIDGET (dialog));
2334     }
2335   else
2336     {
2337       gchar *geometry_string = g_strdup (gtk_entry_get_text (entry));
2338       gchar *title = g_strdup_printf ("Gridded window at: %s", geometry_string);
2339       GtkWidget *window;
2340       GtkWidget *drawing_area;
2341       GtkWidget *box;
2342       GdkGeometry geometry;
2343       
2344       window = gtk_dialog_new_with_buttons (title,
2345                                             NULL, 0,
2346                                             "Reset", 1,
2347                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
2348                                             NULL);
2349
2350       gtk_window_set_screen (GTK_WINDOW (window), 
2351                              gtk_widget_get_screen (GTK_WIDGET (dialog)));
2352       g_free (title);
2353       g_signal_connect (window, "response",
2354                         G_CALLBACK (gridded_geometry_subresponse), geometry_string);
2355
2356       box = gtk_vbox_new (FALSE, 0);
2357       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), box, TRUE, TRUE, 0);
2358       
2359       gtk_container_set_border_width (GTK_CONTAINER (box), 7);
2360       
2361       drawing_area = gtk_drawing_area_new ();
2362       g_signal_connect (drawing_area, "expose_event",
2363                         G_CALLBACK (gridded_geometry_expose), NULL);
2364       gtk_box_pack_start (GTK_BOX (box), drawing_area, TRUE, TRUE, 0);
2365
2366       /* Gross hack to work around bug 68668... if we set the size request
2367        * large enough, then  the current
2368        *
2369        *   request_of_window - request_of_geometry_widget
2370        *
2371        * method of getting the base size works more or less works.
2372        */
2373       gtk_widget_set_size_request (drawing_area, 2000, 2000);
2374
2375       geometry.base_width = 0;
2376       geometry.base_height = 0;
2377       geometry.min_width = 2 * GRID_SIZE;
2378       geometry.min_height = 2 * GRID_SIZE;
2379       geometry.width_inc = GRID_SIZE;
2380       geometry.height_inc = GRID_SIZE;
2381
2382       gtk_window_set_geometry_hints (GTK_WINDOW (window), drawing_area,
2383                                      &geometry,
2384                                      GDK_HINT_BASE_SIZE | GDK_HINT_MIN_SIZE | GDK_HINT_RESIZE_INC);
2385
2386       if (!gtk_window_parse_geometry (GTK_WINDOW (window), geometry_string))
2387         {
2388           g_print ("Can't parse geometry string %s\n", geometry_string);
2389           gtk_window_parse_geometry (GTK_WINDOW (window), DEFAULT_GEOMETRY);
2390         }
2391
2392       gtk_widget_show_all (window);
2393     }
2394 }
2395
2396 static void 
2397 create_gridded_geometry (GtkWidget *widget)
2398 {
2399   static GtkWidget *window = NULL;
2400   GtkWidget *entry;
2401   GtkWidget *label;
2402
2403   if (!window)
2404     {
2405       window = gtk_dialog_new_with_buttons ("Gridded Geometry",
2406                                             NULL, 0,
2407                                             "Create", 1,
2408                                             GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
2409                                             NULL);
2410       
2411       gtk_window_set_screen (GTK_WINDOW (window),
2412                              gtk_widget_get_screen (widget));
2413
2414       label = gtk_label_new ("Geometry string:");
2415       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label, FALSE, FALSE, 0);
2416
2417       entry = gtk_entry_new ();
2418       gtk_entry_set_text (GTK_ENTRY (entry), DEFAULT_GEOMETRY);
2419       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), entry, FALSE, FALSE, 0);
2420
2421       g_signal_connect (window, "response",
2422                         G_CALLBACK (gridded_geometry_response), entry);
2423       g_object_add_weak_pointer (G_OBJECT (window), (gpointer) &window);
2424
2425       gtk_widget_show_all (window);
2426     }
2427   else
2428     gtk_widget_destroy (window);
2429 }
2430
2431 /*
2432  * GtkHandleBox
2433  */
2434
2435 static void
2436 handle_box_child_signal (GtkHandleBox *hb,
2437                          GtkWidget    *child,
2438                          const gchar  *action)
2439 {
2440   printf ("%s: child <%s> %sed\n",
2441           g_type_name (G_OBJECT_TYPE (hb)),
2442           g_type_name (G_OBJECT_TYPE (child)),
2443           action);
2444 }
2445
2446 static void
2447 create_handle_box (GtkWidget *widget)
2448 {
2449   static GtkWidget* window = NULL;
2450   GtkWidget *handle_box;
2451   GtkWidget *handle_box2;
2452   GtkWidget *vbox;
2453   GtkWidget *hbox;
2454   GtkWidget *toolbar;
2455   GtkWidget *label;
2456   GtkWidget *separator;
2457
2458   if (!window)
2459   {
2460     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2461     
2462     gtk_window_set_screen (GTK_WINDOW (window),
2463                            gtk_widget_get_screen (widget));
2464     gtk_window_set_modal (GTK_WINDOW (window), FALSE);
2465     gtk_window_set_title (GTK_WINDOW (window),
2466                           "Handle Box Test");
2467     gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2468     
2469     g_signal_connect (window, "destroy",
2470                       G_CALLBACK (gtk_widget_destroyed),
2471                       &window);
2472     
2473     gtk_container_set_border_width (GTK_CONTAINER (window), 20);
2474
2475     vbox = gtk_vbox_new (FALSE, 0);
2476     gtk_container_add (GTK_CONTAINER (window), vbox);
2477     gtk_widget_show (vbox);
2478
2479     label = gtk_label_new ("Above");
2480     gtk_container_add (GTK_CONTAINER (vbox), label);
2481     gtk_widget_show (label);
2482
2483     separator = gtk_hseparator_new ();
2484     gtk_container_add (GTK_CONTAINER (vbox), separator);
2485     gtk_widget_show (separator);
2486     
2487     hbox = gtk_hbox_new (FALSE, 10);
2488     gtk_container_add (GTK_CONTAINER (vbox), hbox);
2489     gtk_widget_show (hbox);
2490
2491     separator = gtk_hseparator_new ();
2492     gtk_container_add (GTK_CONTAINER (vbox), separator);
2493     gtk_widget_show (separator);
2494
2495     label = gtk_label_new ("Below");
2496     gtk_container_add (GTK_CONTAINER (vbox), label);
2497     gtk_widget_show (label);
2498
2499     handle_box = gtk_handle_box_new ();
2500     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
2501     g_signal_connect (handle_box,
2502                       "child_attached",
2503                       G_CALLBACK (handle_box_child_signal),
2504                       "attached");
2505     g_signal_connect (handle_box,
2506                       "child_detached",
2507                       G_CALLBACK (handle_box_child_signal),
2508                       "detached");
2509     gtk_widget_show (handle_box);
2510
2511     toolbar = make_toolbar (window);
2512     
2513     gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
2514     gtk_widget_show (toolbar);
2515
2516     handle_box = gtk_handle_box_new ();
2517     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
2518     g_signal_connect (handle_box,
2519                       "child_attached",
2520                       G_CALLBACK (handle_box_child_signal),
2521                       "attached");
2522     g_signal_connect (handle_box,
2523                       "child_detached",
2524                       G_CALLBACK (handle_box_child_signal),
2525                       "detached");
2526     gtk_widget_show (handle_box);
2527
2528     handle_box2 = gtk_handle_box_new ();
2529     gtk_container_add (GTK_CONTAINER (handle_box), handle_box2);
2530     g_signal_connect (handle_box2,
2531                       "child_attached",
2532                       G_CALLBACK (handle_box_child_signal),
2533                       "attached");
2534     g_signal_connect (handle_box2,
2535                       "child_detached",
2536                       G_CALLBACK (handle_box_child_signal),
2537                       "detached");
2538     gtk_widget_show (handle_box2);
2539
2540     hbox = g_object_new (GTK_TYPE_HBOX, "visible", 1, "parent", handle_box2, NULL);
2541     label = gtk_label_new ("Fooo!");
2542     gtk_container_add (GTK_CONTAINER (hbox), label);
2543     gtk_widget_show (label);
2544     g_object_new (GTK_TYPE_ARROW, "visible", 1, "parent", hbox, NULL);
2545   }
2546
2547   if (!GTK_WIDGET_VISIBLE (window))
2548     gtk_widget_show (window);
2549   else
2550     gtk_widget_destroy (window);
2551 }
2552
2553 /*
2554  * Test for getting an image from a drawable
2555  */
2556
2557 struct GetImageData
2558 {
2559   GtkWidget *src;
2560   GtkWidget *snap;
2561   GtkWidget *sw;
2562 };
2563
2564 static void
2565 take_snapshot (GtkWidget *button,
2566                gpointer data)
2567 {
2568   struct GetImageData *gid = data;
2569   GdkRectangle visible;
2570   int width_fraction;
2571   int height_fraction;
2572   GdkGC *gc;
2573   GdkGC *black_gc;
2574   GdkColor color = { 0, 30000, 0, 0 };
2575   GdkRectangle target;
2576   GdkImage *shot;
2577   
2578   /* Do some begin_paint_rect on some random rects, draw some
2579    * distinctive stuff into those rects, then take the snapshot.
2580    * figure out whether any rects were overlapped and report to
2581    * user.
2582    */
2583
2584   visible = gid->sw->allocation;
2585
2586   visible.x = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (gid->sw))->value;
2587   visible.y = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (gid->sw))->value;
2588   
2589   width_fraction = visible.width / 4;
2590   height_fraction = visible.height / 4;
2591
2592   gc = gdk_gc_new (gid->src->window);
2593   black_gc = gid->src->style->black_gc;
2594   
2595   gdk_gc_set_rgb_fg_color (gc, &color);
2596
2597     
2598   target.x = visible.x + width_fraction;
2599   target.y = visible.y + height_fraction * 3;
2600   target.width = width_fraction;
2601   target.height = height_fraction / 2;
2602   
2603   gdk_window_begin_paint_rect (gid->src->window,
2604                                &target);
2605
2606   gdk_draw_rectangle (gid->src->window,
2607                       gc,
2608                       TRUE,
2609                       target.x, target.y,
2610                       target.width, target.height);
2611
2612   gdk_draw_rectangle (gid->src->window,
2613                       black_gc,
2614                       FALSE,
2615                       target.x + 10, target.y + 10,
2616                       target.width - 20, target.height - 20);
2617   
2618   target.x = visible.x + width_fraction;
2619   target.y = visible.y + height_fraction;
2620   target.width = width_fraction;
2621   target.height = height_fraction;
2622   
2623   gdk_window_begin_paint_rect (gid->src->window,
2624                                &target);
2625
2626   gdk_draw_rectangle (gid->src->window,
2627                       gc,
2628                       TRUE,
2629                       target.x, target.y,
2630                       target.width, target.height);
2631
2632   gdk_draw_rectangle (gid->src->window,
2633                       black_gc,
2634                       FALSE,
2635                       target.x + 10, target.y + 10,
2636                       target.width - 20, target.height - 20);
2637   
2638   target.x = visible.x + width_fraction * 3;
2639   target.y = visible.y + height_fraction;
2640   target.width = width_fraction / 2;
2641   target.height = height_fraction;
2642   
2643   gdk_window_begin_paint_rect (gid->src->window,
2644                                &target);
2645
2646   gdk_draw_rectangle (gid->src->window,
2647                       gc,
2648                       TRUE,
2649                       target.x, target.y,
2650                       target.width, target.height);
2651
2652   gdk_draw_rectangle (gid->src->window,
2653                       black_gc,
2654                       FALSE,
2655                       target.x + 10, target.y + 10,
2656                       target.width - 20, target.height - 20);
2657   
2658   target.x = visible.x + width_fraction * 2;
2659   target.y = visible.y + height_fraction * 2;
2660   target.width = width_fraction / 4;
2661   target.height = height_fraction / 4;
2662   
2663   gdk_window_begin_paint_rect (gid->src->window,
2664                                &target);
2665
2666   gdk_draw_rectangle (gid->src->window,
2667                       gc,
2668                       TRUE,
2669                       target.x, target.y,
2670                       target.width, target.height);
2671
2672   gdk_draw_rectangle (gid->src->window,
2673                       black_gc,
2674                       FALSE,
2675                       target.x + 10, target.y + 10,
2676                       target.width - 20, target.height - 20);  
2677
2678   target.x += target.width / 2;
2679   target.y += target.width / 2;
2680   
2681   gdk_window_begin_paint_rect (gid->src->window,
2682                                &target);
2683
2684   gdk_draw_rectangle (gid->src->window,
2685                       gc,
2686                       TRUE,
2687                       target.x, target.y,
2688                       target.width, target.height);
2689
2690   gdk_draw_rectangle (gid->src->window,
2691                       black_gc,
2692                       FALSE,
2693                       target.x + 10, target.y + 10,
2694                       target.width - 20, target.height - 20);
2695   
2696   /* Screen shot area */
2697
2698   target.x = visible.x + width_fraction * 1.5;
2699   target.y = visible.y + height_fraction * 1.5;
2700   target.width = width_fraction * 2;
2701   target.height = height_fraction * 2;  
2702
2703   shot = gdk_drawable_get_image (gid->src->window,
2704                                  target.x, target.y,
2705                                  target.width, target.height);
2706
2707   gtk_image_set_from_image (GTK_IMAGE (gid->snap),
2708                             shot, NULL);
2709
2710   g_object_unref (shot);
2711   
2712   gdk_window_end_paint (gid->src->window);
2713   gdk_window_end_paint (gid->src->window);
2714   gdk_window_end_paint (gid->src->window);
2715   gdk_window_end_paint (gid->src->window);
2716   gdk_window_end_paint (gid->src->window);
2717
2718   gdk_draw_rectangle (gid->src->window,
2719                       gid->src->style->black_gc,
2720                       FALSE,
2721                       target.x, target.y,
2722                       target.width, target.height);
2723   
2724   g_object_unref (gc);
2725 }
2726
2727 static gint
2728 image_source_expose (GtkWidget *da,
2729                      GdkEventExpose *event,
2730                      gpointer data)
2731 {
2732   int x = event->area.x;
2733   GdkColor red = { 0, 65535, 0, 0 };
2734   GdkColor green = { 0, 0, 65535, 0 };
2735   GdkColor blue = { 0, 0, 0, 65535 };
2736   GdkGC *gc;
2737
2738   gc = gdk_gc_new (event->window);
2739   
2740   while (x < (event->area.x + event->area.width))
2741     {
2742       switch (x % 7)
2743         {
2744         case 0:
2745         case 1:
2746         case 2:
2747           gdk_gc_set_rgb_fg_color (gc, &red);
2748           break;
2749
2750         case 3:
2751         case 4:
2752         case 5:
2753           gdk_gc_set_rgb_fg_color (gc, &green);
2754           break;
2755
2756         case 6:
2757         case 7:
2758         case 8:
2759           gdk_gc_set_rgb_fg_color (gc, &blue);
2760           break;
2761
2762         default:
2763           g_assert_not_reached ();
2764           break;
2765         }
2766
2767       gdk_draw_line (event->window,
2768                      gc,
2769                      x, event->area.y,
2770                      x, event->area.y + event->area.height);
2771       
2772       ++x;
2773     }
2774
2775   g_object_unref (gc);
2776   
2777   return TRUE;
2778 }
2779
2780 static void
2781 create_get_image (GtkWidget *widget)
2782 {
2783   static GtkWidget *window = NULL;
2784
2785   if (window)
2786     gtk_widget_destroy (window);
2787   else
2788     {
2789       GtkWidget *sw;
2790       GtkWidget *src;
2791       GtkWidget *snap;
2792       GtkWidget *hbox;
2793       GtkWidget *vbox;
2794       GtkWidget *button;
2795       struct GetImageData *gid;
2796
2797       gid = g_new (struct GetImageData, 1);
2798       
2799       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2800       
2801       gtk_window_set_screen (GTK_WINDOW (window),
2802                              gtk_widget_get_screen (widget));
2803
2804       g_signal_connect (window,
2805                         "destroy",
2806                         G_CALLBACK (gtk_widget_destroyed),
2807                         &window);
2808
2809       g_object_set_data_full (G_OBJECT (window),
2810                               "testgtk-get-image-data",
2811                               gid,
2812                               g_free);
2813       
2814       hbox = gtk_hbox_new (FALSE, 0);
2815       
2816       gtk_container_add (GTK_CONTAINER (window), hbox);
2817       
2818       sw = gtk_scrolled_window_new (NULL, NULL);
2819       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
2820                                       GTK_POLICY_AUTOMATIC,
2821                                       GTK_POLICY_AUTOMATIC);
2822
2823       gid->sw = sw;
2824
2825       gtk_widget_set_size_request (sw, 400, 400);
2826       
2827       src = gtk_drawing_area_new ();
2828       gtk_widget_set_size_request (src, 10000, 10000);
2829
2830       g_signal_connect (src,
2831                         "expose_event",
2832                         G_CALLBACK (image_source_expose),
2833                         gid);
2834       
2835       gid->src = src;
2836       
2837       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
2838                                              src);
2839       
2840       gtk_box_pack_start (GTK_BOX (hbox),
2841                           sw, TRUE, TRUE, 0);
2842
2843
2844       vbox = gtk_vbox_new (FALSE, 3);
2845
2846       snap = gtk_widget_new (GTK_TYPE_IMAGE, NULL);
2847
2848       gid->snap = snap;
2849
2850       sw = gtk_scrolled_window_new (NULL, NULL);
2851       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
2852                                       GTK_POLICY_AUTOMATIC,
2853                                       GTK_POLICY_AUTOMATIC);
2854       gtk_widget_set_size_request (sw, 300, 300);
2855       
2856       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), snap);
2857
2858       gtk_box_pack_end (GTK_BOX (vbox), sw, FALSE, FALSE, 5);
2859
2860       button = gtk_button_new_with_label ("Get image from drawable");
2861
2862       g_signal_connect (button,
2863                         "clicked",
2864                         G_CALLBACK (take_snapshot),
2865                         gid);
2866       
2867       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2868
2869       gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2870       
2871       gtk_widget_show_all (window);
2872     }
2873 }
2874
2875 /* 
2876  * Label Demo
2877  */
2878 static void
2879 sensitivity_toggled (GtkWidget *toggle,
2880                      GtkWidget *widget)
2881 {
2882   gtk_widget_set_sensitive (widget,  GTK_TOGGLE_BUTTON (toggle)->active);  
2883 }
2884
2885 static GtkWidget*
2886 create_sensitivity_control (GtkWidget *widget)
2887 {
2888   GtkWidget *button;
2889
2890   button = gtk_toggle_button_new_with_label ("Sensitive");  
2891
2892   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
2893                                 GTK_WIDGET_IS_SENSITIVE (widget));
2894   
2895   g_signal_connect (button,
2896                     "toggled",
2897                     G_CALLBACK (sensitivity_toggled),
2898                     widget);
2899   
2900   gtk_widget_show_all (button);
2901
2902   return button;
2903 }
2904
2905 static void
2906 set_selectable_recursive (GtkWidget *widget,
2907                           gboolean   setting)
2908 {
2909   if (GTK_IS_CONTAINER (widget))
2910     {
2911       GList *children;
2912       GList *tmp;
2913       
2914       children = gtk_container_get_children (GTK_CONTAINER (widget));
2915       tmp = children;
2916       while (tmp)
2917         {
2918           set_selectable_recursive (tmp->data, setting);
2919
2920           tmp = tmp->next;
2921         }
2922       g_list_free (children);
2923     }
2924   else if (GTK_IS_LABEL (widget))
2925     {
2926       gtk_label_set_selectable (GTK_LABEL (widget), setting);
2927     }
2928 }
2929
2930 static void
2931 selectable_toggled (GtkWidget *toggle,
2932                     GtkWidget *widget)
2933 {
2934   set_selectable_recursive (widget,
2935                             GTK_TOGGLE_BUTTON (toggle)->active);
2936 }
2937
2938 static GtkWidget*
2939 create_selectable_control (GtkWidget *widget)
2940 {
2941   GtkWidget *button;
2942
2943   button = gtk_toggle_button_new_with_label ("Selectable");  
2944
2945   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
2946                                 FALSE);
2947   
2948   g_signal_connect (button,
2949                     "toggled",
2950                     G_CALLBACK (selectable_toggled),
2951                     widget);
2952   
2953   gtk_widget_show_all (button);
2954
2955   return button;
2956 }
2957
2958 void create_labels (GtkWidget *widget)
2959 {
2960   static GtkWidget *window = NULL;
2961   GtkWidget *hbox;
2962   GtkWidget *vbox;
2963   GtkWidget *frame;
2964   GtkWidget *label;
2965   GtkWidget *button;
2966
2967   if (!window)
2968     {
2969       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2970
2971       gtk_window_set_screen (GTK_WINDOW (window),
2972                              gtk_widget_get_screen (widget));
2973
2974       g_signal_connect (window, "destroy",
2975                         G_CALLBACK (gtk_widget_destroyed),
2976                         &window);
2977
2978       gtk_window_set_title (GTK_WINDOW (window), "Label");
2979
2980       vbox = gtk_vbox_new (FALSE, 5);
2981       
2982       hbox = gtk_hbox_new (FALSE, 5);
2983       gtk_container_add (GTK_CONTAINER (window), vbox);
2984
2985       gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2986
2987       button = create_sensitivity_control (hbox);
2988
2989       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2990
2991       button = create_selectable_control (hbox);
2992
2993       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2994       
2995       vbox = gtk_vbox_new (FALSE, 5);
2996       
2997       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2998       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
2999
3000       frame = gtk_frame_new ("Normal Label");
3001       label = gtk_label_new ("This is a Normal label");
3002       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
3003       gtk_container_add (GTK_CONTAINER (frame), label);
3004       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3005
3006       frame = gtk_frame_new ("Multi-line Label");
3007       label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
3008       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
3009       gtk_container_add (GTK_CONTAINER (frame), label);
3010       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3011
3012       frame = gtk_frame_new ("Left Justified Label");
3013       label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird      line");
3014       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
3015       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3016       gtk_container_add (GTK_CONTAINER (frame), label);
3017       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3018
3019       frame = gtk_frame_new ("Right Justified Label");
3020       gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
3021       label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
3022       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
3023       gtk_container_add (GTK_CONTAINER (frame), label);
3024       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3025
3026       frame = gtk_frame_new ("Internationalized Label");
3027       label = gtk_label_new (NULL);
3028       gtk_label_set_markup (GTK_LABEL (label),
3029                             "French (Fran\303\247ais) Bonjour, Salut\n"
3030                             "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"
3031                             "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"
3032                             "Chinese (Simplified) <span lang=\"zh-cn\">\345\205\203\346\260\224 \345\274\200\345\217\221</span>\n"
3033                             "Chinese (Traditional) <span lang=\"zh-tw\">\345\205\203\346\260\243        \351\226\213\347\231\274</span>\n"
3034                             "Japanese <span lang=\"ja\">\345\205\203\346\260\227        \351\226\213\347\231\272</span>");
3035       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3036       gtk_container_add (GTK_CONTAINER (frame), label);
3037       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3038
3039       frame = gtk_frame_new ("Bidirection Label");
3040       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"
3041                              "\342\200\217Hebrew        \327\251\327\234\327\225\327\235");
3042       gtk_container_add (GTK_CONTAINER (frame), label);
3043       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3044
3045       vbox = gtk_vbox_new (FALSE, 5);
3046       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
3047       frame = gtk_frame_new ("Line wrapped label");
3048       label = gtk_label_new ("This is an example of a line-wrapped label.  It should not be taking "\
3049                              "up the entire             "/* big space to test spacing */\
3050                              "width allocated to it, but automatically wraps the words to fit.  "\
3051                              "The time has come, for all good men, to come to the aid of their party.  "\
3052                              "The sixth sheik's six sheep's sick.\n"\
3053                              "     It supports multiple paragraphs correctly, and  correctly   adds "\
3054                              "many          extra  spaces. ");
3055
3056       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
3057       gtk_container_add (GTK_CONTAINER (frame), label);
3058       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3059
3060       frame = gtk_frame_new ("Filled, wrapped label");
3061       label = gtk_label_new ("This is an example of a line-wrapped, filled label.  It should be taking "\
3062                              "up the entire              width allocated to it.  Here is a seneance to prove "\
3063                              "my point.  Here is another sentence. "\
3064                              "Here comes the sun, do de do de do.\n"\
3065                              "    This is a new paragraph.\n"\
3066                              "    This is another newer, longer, better paragraph.  It is coming to an end, "\
3067                              "unfortunately.");
3068       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
3069       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
3070       gtk_container_add (GTK_CONTAINER (frame), label);
3071       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3072
3073       frame = gtk_frame_new ("Underlined label");
3074       label = gtk_label_new ("This label is underlined!\n"
3075                              "This one is underlined (\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257) in quite a funky fashion");
3076       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
3077       gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __  ___ ____ _____");
3078       gtk_container_add (GTK_CONTAINER (frame), label);
3079       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3080
3081       frame = gtk_frame_new ("Markup label");
3082       label = gtk_label_new (NULL);
3083
3084       /* There's also a gtk_label_set_markup() without accel if you
3085        * don't have an accelerator key
3086        */
3087       gtk_label_set_markup_with_mnemonic (GTK_LABEL (label),
3088                                           "This <span foreground=\"blue\" background=\"orange\">label</span> has "
3089                                           "<b>markup</b> _such as "
3090                                           "<big><i>Big Italics</i></big>\n"
3091                                           "<tt>Monospace font</tt>\n"
3092                                           "<u>Underline!</u>\n"
3093                                           "foo\n"
3094                                           "<span foreground=\"green\" background=\"red\">Ugly colors</span>\n"
3095                                           "and nothing on this line,\n"
3096                                           "or this.\n"
3097                                           "or this either\n"
3098                                           "or even on this one\n"
3099                                           "la <big>la <big>la <big>la <big>la</big></big></big></big>\n"
3100                                           "but this _word is <span foreground=\"purple\"><big>purple</big></span>\n"
3101                                           "<span underline=\"double\">We like <sup>superscript</sup> and <sub>subscript</sub> too</span>");
3102
3103       g_assert (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)) == GDK_s);
3104       
3105       gtk_container_add (GTK_CONTAINER (frame), label);
3106       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
3107     }
3108   
3109   if (!GTK_WIDGET_VISIBLE (window))
3110     gtk_widget_show_all (window);
3111   else
3112     gtk_widget_destroy (window);
3113 }
3114
3115 static void
3116 on_angle_scale_changed (GtkRange *range,
3117                         GtkLabel *label)
3118 {
3119   gtk_label_set_angle (GTK_LABEL (label), gtk_range_get_value (range));
3120 }
3121
3122 static void
3123 create_rotated_label (GtkWidget *widget)
3124 {
3125   static GtkWidget *window = NULL;
3126   GtkWidget *vbox;
3127   GtkWidget *hscale;
3128   GtkWidget *label;  
3129   GtkWidget *scale_label;  
3130   GtkWidget *scale_hbox;  
3131
3132   if (!window)
3133     {
3134       window = gtk_dialog_new_with_buttons ("Rotated Label",
3135                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
3136                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3137                                             NULL);
3138
3139       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
3140
3141       gtk_window_set_screen (GTK_WINDOW (window),
3142                              gtk_widget_get_screen (widget));
3143
3144       g_signal_connect (window, "response",
3145                         G_CALLBACK (gtk_object_destroy), NULL);
3146       g_signal_connect (window, "destroy",
3147                         G_CALLBACK (gtk_widget_destroyed), &window);
3148
3149       vbox = gtk_vbox_new (FALSE, 5);
3150       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 0);
3151       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
3152
3153       label = gtk_label_new (NULL);
3154       gtk_label_set_markup (GTK_LABEL (label), "Hello World\n<i>Rotate</i> <span underline='single' foreground='blue'>me</span>");
3155       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
3156
3157       scale_hbox = gtk_hbox_new (FALSE, 0);
3158       gtk_box_pack_start (GTK_BOX (vbox), scale_hbox, FALSE, FALSE, 0);
3159       
3160       scale_label = gtk_label_new (NULL);
3161       gtk_label_set_markup (GTK_LABEL (scale_label), "<i>Angle: </i>");
3162       gtk_box_pack_start (GTK_BOX (scale_hbox), scale_label, FALSE, FALSE, 0);
3163
3164       hscale = gtk_hscale_new_with_range (0, 360, 5);
3165       g_signal_connect (hscale, "value-changed",
3166                         G_CALLBACK (on_angle_scale_changed), label);
3167       
3168       gtk_range_set_value (GTK_RANGE (hscale), 45);
3169       gtk_widget_set_usize (hscale, 200, -1);
3170       gtk_box_pack_start (GTK_BOX (scale_hbox), hscale, TRUE, TRUE, 0);
3171     }
3172   
3173   if (!GTK_WIDGET_VISIBLE (window))
3174     gtk_widget_show_all (window);
3175   else
3176     gtk_widget_destroy (window);
3177 }
3178
3179 #define DEFAULT_TEXT_RADIUS 200
3180
3181 static void
3182 on_rotated_text_unrealize (GtkWidget *widget)
3183 {
3184   g_object_set_data (G_OBJECT (widget), "text-gc", NULL);
3185 }
3186
3187 static gboolean
3188 on_rotated_text_expose (GtkWidget      *widget,
3189                         GdkEventExpose *event,
3190                         GdkPixbuf      *tile_pixbuf)
3191 {
3192   static const gchar *words[] = { "The", "grand", "old", "Duke", "of", "York",
3193                                   "had", "10,000", "men" };
3194   PangoRenderer *renderer;
3195   GdkGC *gc;
3196   int n_words;
3197   int i;
3198   double radius;
3199   PangoMatrix matrix = PANGO_MATRIX_INIT;
3200   PangoLayout *layout;
3201   PangoContext *context;
3202   PangoFontDescription *desc;
3203
3204   gc = g_object_get_data (G_OBJECT (widget), "text-gc");
3205   if (!gc)
3206     {
3207       static GdkColor black = { 0, 0, 0, 0 };
3208       
3209       gc = gdk_gc_new (widget->window);
3210       gdk_gc_set_rgb_fg_color (gc, &black);
3211       
3212       if (tile_pixbuf)
3213         {
3214           GdkPixmap *tile;
3215           
3216           gint width = gdk_pixbuf_get_width (tile_pixbuf);
3217           gint height = gdk_pixbuf_get_height (tile_pixbuf);
3218           
3219           tile = gdk_pixmap_new (widget->window, width, height, -1);
3220           gdk_draw_pixbuf (tile, gc, tile_pixbuf,
3221                            0, 0, 0, 0, width, height,
3222                            GDK_RGB_DITHER_NORMAL, 0, 0);
3223
3224           gdk_gc_set_tile (gc, tile);
3225           gdk_gc_set_fill (gc, GDK_TILED);
3226
3227           g_object_unref (tile);
3228         }
3229
3230       g_object_set_data_full (G_OBJECT (widget), "text-gc", gc, (GDestroyNotify)g_object_unref);
3231     }
3232
3233   renderer = gdk_pango_renderer_get_default (gtk_widget_get_screen (widget));
3234   gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), widget->window);
3235   gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), gc);
3236
3237   radius = MIN (widget->allocation.width, widget->allocation.height) / 2.;
3238
3239   pango_matrix_translate (&matrix,
3240                           radius + (widget->allocation.width - 2 * radius) / 2,
3241                           radius + (widget->allocation.height - 2 * radius) / 2);
3242   pango_matrix_scale (&matrix, radius / DEFAULT_TEXT_RADIUS, radius / DEFAULT_TEXT_RADIUS);
3243
3244   context = gtk_widget_get_pango_context (widget);
3245   layout = pango_layout_new (context);
3246   desc = pango_font_description_from_string ("Sans Bold 30");
3247   pango_layout_set_font_description (layout, desc);
3248   pango_font_description_free (desc);
3249     
3250   n_words = G_N_ELEMENTS (words);
3251   for (i = 0; i < n_words; i++)
3252     {
3253       PangoMatrix rotated_matrix = matrix;
3254       int width, height;
3255       
3256       pango_matrix_rotate (&rotated_matrix, - (360. * i) / n_words);
3257
3258       pango_context_set_matrix (context, &rotated_matrix);
3259       pango_layout_context_changed (layout);
3260       pango_layout_set_text (layout, words[i], -1);
3261       
3262       pango_layout_get_size (layout, &width, &height);
3263
3264       pango_renderer_draw_layout (renderer, layout,
3265                                   - width / 2, - DEFAULT_TEXT_RADIUS * PANGO_SCALE);
3266     }
3267
3268   gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), NULL);
3269   gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), NULL);
3270   
3271   g_object_unref (layout);
3272
3273   return FALSE;
3274 }
3275
3276 static void
3277 create_rotated_text (GtkWidget *widget)
3278 {
3279   static GtkWidget *window = NULL;
3280
3281   if (!window)
3282     {
3283       const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
3284       GtkRequisition requisition;
3285       GtkWidget *drawing_area;
3286       GdkPixbuf *tile_pixbuf;
3287
3288       window = gtk_dialog_new_with_buttons ("Rotated Text",
3289                                             GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
3290                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
3291                                             NULL);
3292
3293       gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
3294
3295       gtk_window_set_screen (GTK_WINDOW (window),
3296                              gtk_widget_get_screen (widget));
3297
3298       g_signal_connect (window, "response",
3299                         G_CALLBACK (gtk_object_destroy), NULL);
3300       g_signal_connect (window, "destroy",
3301                         G_CALLBACK (gtk_widget_destroyed), &window);
3302
3303       drawing_area = gtk_drawing_area_new ();
3304       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), drawing_area, TRUE, TRUE, 0);
3305       gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white);
3306
3307       tile_pixbuf = gdk_pixbuf_new_from_file ("marble.xpm", NULL);
3308       
3309       g_signal_connect (drawing_area, "expose-event",
3310                         G_CALLBACK (on_rotated_text_expose), tile_pixbuf);
3311       g_signal_connect (drawing_area, "unrealize",
3312                         G_CALLBACK (on_rotated_text_unrealize), NULL);
3313
3314       gtk_widget_show_all (GTK_BIN (window)->child);
3315       
3316       gtk_widget_set_size_request (drawing_area, DEFAULT_TEXT_RADIUS * 2, DEFAULT_TEXT_RADIUS * 2);
3317       gtk_widget_size_request (window, &requisition);
3318       gtk_widget_set_size_request (drawing_area, -1, -1);
3319       gtk_window_resize (GTK_WINDOW (window), requisition.width, requisition.height);
3320     }
3321   
3322   if (!GTK_WIDGET_VISIBLE (window))
3323     gtk_widget_show (window);
3324   else
3325     gtk_widget_destroy (window);
3326 }
3327
3328 /*
3329  * Reparent demo
3330  */
3331
3332 static void
3333 reparent_label (GtkWidget *widget,
3334                 GtkWidget *new_parent)
3335 {
3336   GtkWidget *label;
3337
3338   label = g_object_get_data (G_OBJECT (widget), "user_data");
3339
3340   gtk_widget_reparent (label, new_parent);
3341 }
3342
3343 static void
3344 set_parent_signal (GtkWidget *child,
3345                    GtkWidget *old_parent,
3346                    gpointer   func_data)
3347 {
3348   g_message ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
3349              g_type_name (G_OBJECT_TYPE (child)),
3350              child->parent ? g_type_name (G_OBJECT_TYPE (child->parent)) : "NULL",
3351              old_parent ? g_type_name (G_OBJECT_TYPE (old_parent)) : "NULL",
3352              GPOINTER_TO_INT (func_data));
3353 }
3354
3355 static void
3356 create_reparent (GtkWidget *widget)
3357 {
3358   static GtkWidget *window = NULL;
3359   GtkWidget *box1;
3360   GtkWidget *box2;
3361   GtkWidget *box3;
3362   GtkWidget *frame;
3363   GtkWidget *button;
3364   GtkWidget *label;
3365   GtkWidget *separator;
3366   GtkWidget *event_box;
3367
3368   if (!window)
3369     {
3370       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3371
3372       gtk_window_set_screen (GTK_WINDOW (window),
3373                              gtk_widget_get_screen (widget));
3374
3375       g_signal_connect (window, "destroy",
3376                         G_CALLBACK (gtk_widget_destroyed),
3377                         &window);
3378
3379       gtk_window_set_title (GTK_WINDOW (window), "reparent");
3380       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3381
3382       box1 = gtk_vbox_new (FALSE, 0);
3383       gtk_container_add (GTK_CONTAINER (window), box1);
3384
3385       box2 = gtk_hbox_new (FALSE, 5);
3386       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3387       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3388
3389       label = gtk_label_new ("Hello World");
3390
3391       frame = gtk_frame_new ("Frame 1");
3392       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
3393
3394       box3 = gtk_vbox_new (FALSE, 5);
3395       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
3396       gtk_container_add (GTK_CONTAINER (frame), box3);
3397
3398       button = gtk_button_new_with_label ("switch");
3399       g_object_set_data (G_OBJECT (button), "user_data", label);
3400       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
3401
3402       event_box = gtk_event_box_new ();
3403       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
3404       gtk_container_add (GTK_CONTAINER (event_box), label);
3405                          
3406       g_signal_connect (button, "clicked",
3407                         G_CALLBACK (reparent_label),
3408                         event_box);
3409       
3410       g_signal_connect (label, "parent_set",
3411                         G_CALLBACK (set_parent_signal),
3412                         GINT_TO_POINTER (42));
3413
3414       frame = gtk_frame_new ("Frame 2");
3415       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
3416
3417       box3 = gtk_vbox_new (FALSE, 5);
3418       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
3419       gtk_container_add (GTK_CONTAINER (frame), box3);
3420
3421       button = gtk_button_new_with_label ("switch");
3422       g_object_set_data (G_OBJECT (button), "user_data", label);
3423       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
3424       
3425       event_box = gtk_event_box_new ();
3426       gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
3427
3428       g_signal_connect (button, "clicked",
3429                         G_CALLBACK (reparent_label),
3430                         event_box);
3431
3432       separator = gtk_hseparator_new ();
3433       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3434
3435       box2 = gtk_vbox_new (FALSE, 10);
3436       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3437       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3438
3439       button = gtk_button_new_with_label ("close");
3440       g_signal_connect_swapped (button, "clicked",
3441                                 G_CALLBACK (gtk_widget_destroy), window);
3442       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3443       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3444       gtk_widget_grab_default (button);
3445     }
3446
3447   if (!GTK_WIDGET_VISIBLE (window))
3448     gtk_widget_show_all (window);
3449   else
3450     gtk_widget_destroy (window);
3451 }
3452
3453 /*
3454  * Resize Grips
3455  */
3456 static gboolean
3457 grippy_button_press (GtkWidget *area, GdkEventButton *event, GdkWindowEdge edge)
3458 {
3459   if (event->type == GDK_BUTTON_PRESS) 
3460     {
3461       if (event->button == 1)
3462         gtk_window_begin_resize_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), edge,
3463                                       event->button, event->x_root, event->y_root,
3464                                       event->time);
3465       else if (event->button == 2)
3466         gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), 
3467                                     event->button, event->x_root, event->y_root,
3468                                     event->time);
3469     }
3470   return TRUE;
3471 }
3472
3473 static gboolean
3474 grippy_expose (GtkWidget *area, GdkEventExpose *event, GdkWindowEdge edge)
3475 {
3476   gtk_paint_resize_grip (area->style,
3477                          area->window,
3478                          GTK_WIDGET_STATE (area),
3479                          &event->area,
3480                          area,
3481                          "statusbar",
3482                          edge,
3483                          0, 0,
3484                          area->allocation.width,
3485                          area->allocation.height);
3486
3487   return TRUE;
3488 }
3489
3490 static void
3491 create_resize_grips (GtkWidget *widget)
3492 {
3493   static GtkWidget *window = NULL;
3494   GtkWidget *area;
3495   GtkWidget *hbox, *vbox;
3496   if (!window)
3497     {
3498       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3499
3500       gtk_window_set_screen (GTK_WINDOW (window),
3501                              gtk_widget_get_screen (widget));
3502
3503       gtk_window_set_title (GTK_WINDOW (window), "resize grips");
3504       
3505       g_signal_connect (window, "destroy",
3506                         G_CALLBACK (gtk_widget_destroyed),
3507                         &window);
3508
3509       vbox = gtk_vbox_new (FALSE, 0);
3510       gtk_container_add (GTK_CONTAINER (window), vbox);
3511       
3512       hbox = gtk_hbox_new (FALSE, 0);
3513       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
3514
3515       /* North west */
3516       area = gtk_drawing_area_new ();
3517       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3518       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3519       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3520                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
3521       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3522                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
3523       
3524       /* North */
3525       area = gtk_drawing_area_new ();
3526       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3527       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3528       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3529                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
3530       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3531                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
3532
3533       /* North east */
3534       area = gtk_drawing_area_new ();
3535       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3536       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3537       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3538                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
3539       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3540                         GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
3541
3542       hbox = gtk_hbox_new (FALSE, 0);
3543       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
3544
3545       /* West */
3546       area = gtk_drawing_area_new ();
3547       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3548       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3549       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3550                         GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
3551       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3552                         GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
3553
3554       /* Middle */
3555       area = gtk_drawing_area_new ();
3556       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3557
3558       /* East */
3559       area = gtk_drawing_area_new ();
3560       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3561       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3562       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3563                         GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
3564       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3565                         GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
3566
3567
3568       hbox = gtk_hbox_new (FALSE, 0);
3569       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
3570
3571       /* South west */
3572       area = gtk_drawing_area_new ();
3573       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3574       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3575       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3576                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
3577       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3578                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
3579       /* South */
3580       area = gtk_drawing_area_new ();
3581       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3582       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3583       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3584                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
3585       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3586                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
3587       
3588       /* South east */
3589       area = gtk_drawing_area_new ();
3590       gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
3591       gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
3592       g_signal_connect (area, "expose_event", G_CALLBACK (grippy_expose),
3593                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
3594       g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
3595                         GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
3596     }
3597
3598   if (!GTK_WIDGET_VISIBLE (window))
3599     gtk_widget_show_all (window);
3600   else
3601     gtk_widget_destroy (window);
3602 }
3603
3604 /*
3605  * Saved Position
3606  */
3607 gint upositionx = 0;
3608 gint upositiony = 0;
3609
3610 static gint
3611 uposition_configure (GtkWidget *window)
3612 {
3613   GtkLabel *lx;
3614   GtkLabel *ly;
3615   gchar buffer[64];
3616
3617   lx = g_object_get_data (G_OBJECT (window), "x");
3618   ly = g_object_get_data (G_OBJECT (window), "y");
3619
3620   gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
3621   sprintf (buffer, "%d", upositionx);
3622   gtk_label_set_text (lx, buffer);
3623   sprintf (buffer, "%d", upositiony);
3624   gtk_label_set_text (ly, buffer);
3625
3626   return FALSE;
3627 }
3628
3629 static void
3630 uposition_stop_configure (GtkToggleButton *toggle,
3631                           GtkObject       *window)
3632 {
3633   if (toggle->active)
3634     g_signal_handlers_block_by_func (window, G_CALLBACK (uposition_configure), NULL);
3635   else
3636     g_signal_handlers_unblock_by_func (window, G_CALLBACK (uposition_configure), NULL);
3637 }
3638
3639 static void
3640 create_saved_position (GtkWidget *widget)
3641 {
3642   static GtkWidget *window = NULL;
3643
3644   if (!window)
3645     {
3646       GtkWidget *hbox;
3647       GtkWidget *main_vbox;
3648       GtkWidget *vbox;
3649       GtkWidget *x_label;
3650       GtkWidget *y_label;
3651       GtkWidget *button;
3652       GtkWidget *label;
3653       GtkWidget *any;
3654
3655       window = g_object_connect (gtk_widget_new (GTK_TYPE_WINDOW,
3656                                                  "type", GTK_WINDOW_TOPLEVEL,
3657                                                  "title", "Saved Position",
3658                                                  NULL),
3659                                  "signal::configure_event", uposition_configure, NULL,
3660                                  NULL);
3661
3662       gtk_window_move (GTK_WINDOW (window), upositionx, upositiony);
3663
3664       gtk_window_set_screen (GTK_WINDOW (window),
3665                              gtk_widget_get_screen (widget));
3666       
3667
3668       g_signal_connect (window, "destroy",
3669                         G_CALLBACK (gtk_widget_destroyed),
3670                         &window);
3671
3672       main_vbox = gtk_vbox_new (FALSE, 5);
3673       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
3674       gtk_container_add (GTK_CONTAINER (window), main_vbox);
3675
3676       vbox =
3677         gtk_widget_new (gtk_vbox_get_type (),
3678                         "GtkBox::homogeneous", FALSE,
3679                         "GtkBox::spacing", 5,
3680                         "GtkContainer::border_width", 10,
3681                         "GtkWidget::parent", main_vbox,
3682                         "GtkWidget::visible", TRUE,
3683                         "child", g_object_connect (gtk_widget_new (GTK_TYPE_TOGGLE_BUTTON,
3684                                                                    "label", "Stop Events",
3685                                                                    "active", FALSE,
3686                                                                    "visible", TRUE,
3687                                                                    NULL),
3688                                                    "signal::clicked", uposition_stop_configure, window,
3689                                                    NULL),
3690                         NULL);
3691
3692       hbox = gtk_hbox_new (FALSE, 0);
3693       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3694       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3695
3696       label = gtk_label_new ("X Origin : ");
3697       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3698       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3699
3700       x_label = gtk_label_new ("");
3701       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
3702       g_object_set_data (G_OBJECT (window), "x", x_label);
3703
3704       hbox = gtk_hbox_new (FALSE, 0);
3705       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3706       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3707
3708       label = gtk_label_new ("Y Origin : ");
3709       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3710       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3711
3712       y_label = gtk_label_new ("");
3713       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
3714       g_object_set_data (G_OBJECT (window), "y", y_label);
3715
3716       any =
3717         gtk_widget_new (gtk_hseparator_get_type (),
3718                         "GtkWidget::visible", TRUE,
3719                         NULL);
3720       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
3721
3722       hbox = gtk_hbox_new (FALSE, 0);
3723       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
3724       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
3725
3726       button = gtk_button_new_with_label ("Close");
3727       g_signal_connect_swapped (button, "clicked",
3728                                 G_CALLBACK (gtk_widget_destroy),
3729                                 window);
3730       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3731       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3732       gtk_widget_grab_default (button);
3733       
3734       gtk_widget_show_all (window);
3735     }
3736   else
3737     gtk_widget_destroy (window);
3738 }
3739
3740 /*
3741  * GtkPixmap
3742  */
3743
3744 static void
3745 create_pixmap (GtkWidget *widget)
3746 {
3747   static GtkWidget *window = NULL;
3748   GtkWidget *box1;
3749   GtkWidget *box2;
3750   GtkWidget *box3;
3751   GtkWidget *button;
3752   GtkWidget *label;
3753   GtkWidget *separator;
3754   GtkWidget *pixmapwid;
3755
3756   if (!window)
3757     {
3758       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3759
3760       gtk_window_set_screen (GTK_WINDOW (window),
3761                              gtk_widget_get_screen (widget));
3762
3763       g_signal_connect (window, "destroy",
3764                         G_CALLBACK (gtk_widget_destroyed),
3765                         &window);
3766
3767       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
3768       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3769       gtk_widget_realize(window);
3770
3771       box1 = gtk_vbox_new (FALSE, 0);
3772       gtk_container_add (GTK_CONTAINER (window), box1);
3773
3774       box2 = gtk_vbox_new (FALSE, 10);
3775       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3776       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3777
3778       button = gtk_button_new ();
3779       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
3780
3781       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
3782
3783       label = gtk_label_new ("Pixmap\ntest");
3784       box3 = gtk_hbox_new (FALSE, 0);
3785       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
3786       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
3787       gtk_container_add (GTK_CONTAINER (box3), label);
3788       gtk_container_add (GTK_CONTAINER (button), box3);
3789
3790       button = gtk_button_new ();
3791       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
3792       
3793       pixmapwid = new_pixmap ("test.xpm", window->window, NULL);
3794
3795       label = gtk_label_new ("Pixmap\ntest");
3796       box3 = gtk_hbox_new (FALSE, 0);
3797       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
3798       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
3799       gtk_container_add (GTK_CONTAINER (box3), label);
3800       gtk_container_add (GTK_CONTAINER (button), box3);
3801
3802       gtk_widget_set_sensitive (button, FALSE);
3803       
3804       separator = gtk_hseparator_new ();
3805       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3806
3807       box2 = gtk_vbox_new (FALSE, 10);
3808       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3809       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3810
3811       button = gtk_button_new_with_label ("close");
3812       g_signal_connect_swapped (button, "clicked",
3813                                 G_CALLBACK (gtk_widget_destroy),
3814                                 window);
3815       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3816       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3817       gtk_widget_grab_default (button);
3818     }
3819
3820   if (!GTK_WIDGET_VISIBLE (window))
3821     gtk_widget_show_all (window);
3822   else
3823     gtk_widget_destroy (window);
3824 }
3825
3826 static void
3827 tips_query_widget_entered (GtkTipsQuery   *tips_query,
3828                            GtkWidget      *widget,
3829                            const gchar    *tip_text,
3830                            const gchar    *tip_private,
3831                            GtkWidget      *toggle)
3832 {
3833   if (GTK_TOGGLE_BUTTON (toggle)->active)
3834     {
3835       gtk_label_set_text (GTK_LABEL (tips_query), tip_text ? "There is a Tip!" : "There is no Tip!");
3836       /* don't let GtkTipsQuery reset its label */
3837       g_signal_stop_emission_by_name (tips_query, "widget_entered");
3838     }
3839 }
3840
3841 static gint
3842 tips_query_widget_selected (GtkWidget      *tips_query,
3843                             GtkWidget      *widget,
3844                             const gchar    *tip_text,
3845                             const gchar    *tip_private,
3846                             GdkEventButton *event,
3847                             gpointer        func_data)
3848 {
3849   if (widget)
3850     g_print ("Help \"%s\" requested for <%s>\n",
3851              tip_private ? tip_private : "None",
3852              g_type_name (G_OBJECT_TYPE (widget)));
3853   return TRUE;
3854 }
3855
3856 static void
3857 create_tooltips (GtkWidget *widget)
3858 {
3859   static GtkWidget *window = NULL;
3860   GtkWidget *box1;
3861   GtkWidget *box2;
3862   GtkWidget *box3;
3863   GtkWidget *button;
3864   GtkWidget *toggle;
3865   GtkWidget *frame;
3866   GtkWidget *tips_query;
3867   GtkWidget *separator;
3868   GtkTooltips *tooltips;
3869
3870   if (!window)
3871     {
3872       window =
3873         gtk_widget_new (gtk_window_get_type (),
3874                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
3875                         "GtkContainer::border_width", 0,
3876                         "GtkWindow::title", "Tooltips",
3877                         "GtkWindow::allow_shrink", TRUE,
3878                         "GtkWindow::allow_grow", FALSE,
3879                         NULL);
3880
3881       gtk_window_set_screen (GTK_WINDOW (window),
3882                              gtk_widget_get_screen (widget));
3883
3884       g_signal_connect (window, "destroy",
3885                         G_CALLBACK (destroy_tooltips),
3886                         &window);
3887
3888       tooltips=gtk_tooltips_new();
3889       g_object_ref (tooltips);
3890       gtk_object_sink (GTK_OBJECT (tooltips));
3891       g_object_set_data (G_OBJECT (window), "tooltips", tooltips);
3892       
3893       box1 = gtk_vbox_new (FALSE, 0);
3894       gtk_container_add (GTK_CONTAINER (window), box1);
3895
3896       box2 = gtk_vbox_new (FALSE, 10);
3897       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3898       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3899
3900       button = gtk_toggle_button_new_with_label ("button1");
3901       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3902
3903       gtk_tooltips_set_tip (tooltips,
3904                             button,
3905                             "This is button 1",
3906                             "ContextHelp/buttons/1");
3907
3908       button = gtk_toggle_button_new_with_label ("button2");
3909       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3910
3911       gtk_tooltips_set_tip (tooltips,
3912                             button,
3913                             "This is button 2. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly.",
3914                             "ContextHelp/buttons/2_long");
3915
3916       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
3917       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
3918
3919       gtk_tooltips_set_tip (tooltips,
3920                             toggle,
3921                             "Toggle TipsQuery view.",
3922                             "Hi msw! ;)");
3923
3924       box3 =
3925         gtk_widget_new (gtk_vbox_get_type (),
3926                         "homogeneous", FALSE,
3927                         "spacing", 5,
3928                         "border_width", 5,
3929                         "visible", TRUE,
3930                         NULL);
3931
3932       tips_query = gtk_tips_query_new ();
3933
3934       button =
3935         gtk_widget_new (gtk_button_get_type (),
3936                         "label", "[?]",
3937                         "visible", TRUE,
3938                         "parent", box3,
3939                         NULL);
3940       g_object_connect (button,
3941                         "swapped_signal::clicked", gtk_tips_query_start_query, tips_query,
3942                         NULL);
3943       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
3944       gtk_tooltips_set_tip (tooltips,
3945                             button,
3946                             "Start the Tooltips Inspector",
3947                             "ContextHelp/buttons/?");
3948       
3949       
3950       g_object_set (g_object_connect (tips_query,
3951                                       "signal::widget_entered", tips_query_widget_entered, toggle,
3952                                       "signal::widget_selected", tips_query_widget_selected, NULL,
3953                                       NULL),
3954                     "visible", TRUE,
3955                     "parent", box3,
3956                     "caller", button,
3957                     NULL);
3958       
3959       frame = gtk_widget_new (gtk_frame_get_type (),
3960                               "label", "ToolTips Inspector",
3961                               "label_xalign", (double) 0.5,
3962                               "border_width", 0,
3963                               "visible", TRUE,
3964                               "parent", box2,
3965                               "child", box3,
3966                               NULL);
3967       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
3968
3969       separator = gtk_hseparator_new ();
3970       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3971
3972       box2 = gtk_vbox_new (FALSE, 10);
3973       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3974       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3975
3976       button = gtk_button_new_with_label ("close");
3977       g_signal_connect_swapped (button, "clicked",
3978                                 G_CALLBACK (gtk_widget_destroy),
3979                                 window);
3980       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3981       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3982       gtk_widget_grab_default (button);
3983
3984       gtk_tooltips_set_tip (tooltips, button, "Push this button to close window", "ContextHelp/buttons/Close");
3985     }
3986
3987   if (!GTK_WIDGET_VISIBLE (window))
3988     gtk_widget_show_all (window);
3989   else
3990     gtk_widget_destroy (window);
3991 }
3992
3993 /*
3994  * GtkImage
3995  */
3996
3997 static void
3998 pack_image (GtkWidget *box,
3999             const gchar *text,
4000             GtkWidget *image)
4001 {
4002   gtk_box_pack_start (GTK_BOX (box),
4003                       gtk_label_new (text),
4004                       FALSE, FALSE, 0);
4005
4006   gtk_box_pack_start (GTK_BOX (box),
4007                       image,
4008                       TRUE, TRUE, 0);  
4009 }
4010
4011 static void
4012 create_image (GtkWidget *widget)
4013 {
4014   static GtkWidget *window = NULL;
4015
4016   if (window == NULL)
4017     {
4018       GtkWidget *vbox;
4019       GdkPixmap *pixmap;
4020       GdkBitmap *mask;
4021         
4022       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4023       
4024       gtk_window_set_screen (GTK_WINDOW (window),
4025                              gtk_widget_get_screen (widget));
4026
4027       /* this is bogus for testing drawing when allocation < request,
4028        * don't copy into real code
4029        */
4030       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
4031       
4032       g_signal_connect (window, "destroy",
4033                         G_CALLBACK (gtk_widget_destroyed),
4034                         &window);
4035
4036       vbox = gtk_vbox_new (FALSE, 5);
4037
4038       gtk_container_add (GTK_CONTAINER (window), vbox);
4039
4040       pack_image (vbox, "Stock Warning Dialog",
4041                   gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
4042                                             GTK_ICON_SIZE_DIALOG));
4043
4044       pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
4045                                                       gtk_widget_get_colormap (window),
4046                                                       &mask,
4047                                                       NULL,
4048                                                       openfile);
4049       
4050       pack_image (vbox, "Pixmap",
4051                   gtk_image_new_from_pixmap (pixmap, mask));
4052     }
4053
4054   if (!GTK_WIDGET_VISIBLE (window))
4055     gtk_widget_show_all (window);
4056   else
4057     gtk_widget_destroy (window);
4058 }
4059      
4060 /*
4061  * Menu demo
4062  */
4063
4064 static GtkWidget*
4065 create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff)
4066 {
4067   GtkWidget *menu;
4068   GtkWidget *menuitem;
4069   GtkWidget *image;
4070   GSList *group;
4071   char buf[32];
4072   int i, j;
4073
4074   if (depth < 1)
4075     return NULL;
4076
4077   menu = gtk_menu_new ();
4078   gtk_menu_set_screen (GTK_MENU (menu), screen);
4079
4080   group = NULL;
4081
4082   if (tearoff)
4083     {
4084       menuitem = gtk_tearoff_menu_item_new ();
4085       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4086       gtk_widget_show (menuitem);
4087     }
4088
4089   image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
4090                                     GTK_ICON_SIZE_MENU);
4091   gtk_widget_show (image);
4092   menuitem = gtk_image_menu_item_new_with_label ("Image item");
4093   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
4094   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4095   gtk_widget_show (menuitem);
4096   
4097   for (i = 0, j = 1; i < length; i++, j++)
4098     {
4099       sprintf (buf, "item %2d - %d", depth, j);
4100
4101       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
4102       group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
4103
4104 #if 0
4105       if (depth % 2)
4106         gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
4107 #endif
4108
4109       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4110       gtk_widget_show (menuitem);
4111       if (i == 3)
4112         gtk_widget_set_sensitive (menuitem, FALSE);
4113
4114       if (i == 5)
4115         gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem),
4116                                               TRUE);
4117
4118       if (i < 5)
4119         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), 
4120                                    create_menu (screen, depth - 1, 5,  TRUE));
4121     }
4122
4123   return menu;
4124 }
4125
4126 static GtkWidget*
4127 create_table_menu (GdkScreen *screen, gint cols, gint rows, gboolean tearoff)
4128 {
4129   GtkWidget *menu;
4130   GtkWidget *menuitem;
4131   GtkWidget *submenu;
4132   GtkWidget *image;
4133   char buf[32];
4134   int i, j;
4135
4136   menu = gtk_menu_new ();
4137   gtk_menu_set_screen (GTK_MENU (menu), screen);
4138
4139   j = 0;
4140   if (tearoff)
4141     {
4142       menuitem = gtk_tearoff_menu_item_new ();
4143       gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
4144       gtk_widget_show (menuitem);
4145       j++;
4146     }
4147   
4148   menuitem = gtk_menu_item_new_with_label ("items");
4149   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
4150
4151   submenu = gtk_menu_new ();
4152   gtk_menu_set_screen (GTK_MENU (submenu), screen);
4153   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
4154   gtk_widget_show (menuitem);
4155   j++;
4156
4157   /* now fill the items submenu */
4158   image = gtk_image_new_from_stock (GTK_STOCK_HELP,
4159                                     GTK_ICON_SIZE_MENU);
4160   gtk_widget_show (image);
4161   menuitem = gtk_image_menu_item_new_with_label ("Image");
4162   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
4163   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
4164   gtk_widget_show (menuitem);
4165
4166   menuitem = gtk_menu_item_new_with_label ("x");
4167   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 0, 1);
4168   gtk_widget_show (menuitem);
4169
4170   menuitem = gtk_menu_item_new_with_label ("x");
4171   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 2);
4172   gtk_widget_show (menuitem);
4173   
4174   image = gtk_image_new_from_stock (GTK_STOCK_HELP,
4175                                     GTK_ICON_SIZE_MENU);
4176   gtk_widget_show (image);
4177   menuitem = gtk_image_menu_item_new_with_label ("Image");
4178   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
4179   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
4180   gtk_widget_show (menuitem);
4181
4182   menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
4183   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 2, 3);
4184   gtk_widget_show (menuitem);
4185
4186   menuitem = gtk_menu_item_new_with_label ("x");
4187   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 2, 3);
4188   gtk_widget_show (menuitem);
4189
4190   menuitem = gtk_menu_item_new_with_label ("x");
4191   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 3, 4);
4192   gtk_widget_show (menuitem);
4193   
4194   menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
4195   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 3, 4);
4196   gtk_widget_show (menuitem);
4197
4198   menuitem = gtk_check_menu_item_new_with_label ("Check");
4199   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 4, 5);
4200   gtk_widget_show (menuitem);
4201
4202   menuitem = gtk_menu_item_new_with_label ("x");
4203   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 4, 5);
4204   gtk_widget_show (menuitem);
4205
4206   menuitem = gtk_menu_item_new_with_label ("x");
4207   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 5, 6);
4208   gtk_widget_show (menuitem);
4209   
4210   menuitem = gtk_check_menu_item_new_with_label ("Check");
4211   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 5, 6);
4212   gtk_widget_show (menuitem);
4213
4214   menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
4215   gtk_widget_show (menuitem);
4216   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 8);
4217
4218   menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
4219   gtk_widget_show (menuitem);
4220   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 2);
4221
4222   menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
4223   gtk_widget_show (menuitem);
4224   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 0);
4225
4226   menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
4227   gtk_widget_show (menuitem);
4228   gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, -1);
4229   
4230   /* end of items submenu */
4231
4232   menuitem = gtk_menu_item_new_with_label ("spanning");
4233   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
4234
4235   submenu = gtk_menu_new ();
4236   gtk_menu_set_screen (GTK_MENU (submenu), screen);
4237   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
4238   gtk_widget_show (menuitem);
4239   j++;
4240
4241   /* now fill the spanning submenu */
4242   menuitem = gtk_menu_item_new_with_label ("a");
4243   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 2, 0, 1);
4244   gtk_widget_show (menuitem);
4245
4246   menuitem = gtk_menu_item_new_with_label ("b");
4247   gtk_menu_attach (GTK_MENU (submenu), menuitem, 2, 3, 0, 2);
4248   gtk_widget_show (menuitem);
4249
4250   menuitem = gtk_menu_item_new_with_label ("c");
4251   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 3);
4252   gtk_widget_show (menuitem);
4253
4254   menuitem = gtk_menu_item_new_with_label ("d");
4255   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
4256   gtk_widget_show (menuitem);
4257
4258   menuitem = gtk_menu_item_new_with_label ("e");
4259   gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 3, 2, 3);
4260   gtk_widget_show (menuitem);
4261   /* end of spanning submenu */
4262   
4263   menuitem = gtk_menu_item_new_with_label ("left");
4264   gtk_menu_attach (GTK_MENU (menu), menuitem, 0, 1, j, j + 1);
4265   submenu = gtk_menu_new ();
4266   gtk_menu_set_screen (GTK_MENU (submenu), screen);
4267   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
4268   gtk_widget_show (menuitem);
4269
4270   menuitem = gtk_menu_item_new_with_label ("Empty");
4271   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
4272   submenu = gtk_menu_new ();
4273   gtk_menu_set_screen (GTK_MENU (submenu), screen);
4274   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
4275   gtk_widget_show (menuitem);
4276
4277   menuitem = gtk_menu_item_new_with_label ("right");
4278   gtk_menu_attach (GTK_MENU (menu), menuitem, 1, 2, j, j + 1);
4279   submenu = gtk_menu_new ();
4280   gtk_menu_set_screen (GTK_MENU (submenu), screen);
4281   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
4282   gtk_widget_show (menuitem);
4283
4284   menuitem = gtk_menu_item_new_with_label ("Empty");
4285   gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
4286   gtk_widget_show (menuitem);
4287
4288   j++;
4289
4290   for (; j < rows; j++)
4291       for (i = 0; i < cols; i++)
4292       {
4293         sprintf (buf, "(%d %d)", i, j);
4294         menuitem = gtk_menu_item_new_with_label (buf);
4295         gtk_menu_attach (GTK_MENU (menu), menuitem, i, i + 1, j, j + 1);
4296         gtk_widget_show (menuitem);
4297       }
4298   
4299   menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
4300   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 8);
4301   gtk_widget_show (menuitem);
4302   menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
4303   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 2);
4304   gtk_widget_show (menuitem);
4305   menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
4306   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 0);
4307   gtk_widget_show (menuitem);
4308   menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
4309   gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
4310   gtk_widget_show (menuitem);
4311   
4312   return menu;
4313 }
4314
4315 static void
4316 create_menus (GtkWidget *widget)
4317 {
4318   static GtkWidget *window = NULL;
4319   GtkWidget *box1;
4320   GtkWidget *box2;
4321   GtkWidget *button;
4322   GtkWidget *optionmenu;
4323   GtkWidget *separator;
4324   
4325   if (!window)
4326     {
4327       GtkWidget *menubar;
4328       GtkWidget *menu;
4329       GtkWidget *menuitem;
4330       GtkAccelGroup *accel_group;
4331       GtkWidget *image;
4332       GdkScreen *screen = gtk_widget_get_screen (widget);
4333       
4334       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4335
4336       gtk_window_set_screen (GTK_WINDOW (window), screen);
4337       
4338       g_signal_connect (window, "destroy",
4339                         G_CALLBACK (gtk_widget_destroyed),
4340                         &window);
4341       g_signal_connect (window, "delete-event",
4342                         G_CALLBACK (gtk_true),
4343                         NULL);
4344       
4345       accel_group = gtk_accel_group_new ();
4346       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
4347
4348       gtk_window_set_title (GTK_WINDOW (window), "menus");
4349       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4350       
4351       
4352       box1 = gtk_vbox_new (FALSE, 0);
4353       gtk_container_add (GTK_CONTAINER (window), box1);
4354       gtk_widget_show (box1);
4355       
4356       menubar = gtk_menu_bar_new ();
4357       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
4358       gtk_widget_show (menubar);
4359       
4360       menu = create_menu (screen, 2, 50, TRUE);
4361       
4362       menuitem = gtk_menu_item_new_with_label ("test\nline2");
4363       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
4364       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
4365       gtk_widget_show (menuitem);
4366
4367       menu = create_table_menu (screen, 2, 50, TRUE);
4368       
4369       menuitem = gtk_menu_item_new_with_label ("table");
4370       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
4371       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
4372       gtk_widget_show (menuitem);
4373       
4374       menuitem = gtk_menu_item_new_with_label ("foo");
4375       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE));
4376       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
4377       gtk_widget_show (menuitem);
4378
4379       image = gtk_image_new_from_stock (GTK_STOCK_HELP,
4380                                         GTK_ICON_SIZE_MENU);
4381       gtk_widget_show (image);
4382       menuitem = gtk_image_menu_item_new_with_label ("Help");
4383       gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
4384       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 4, 5, TRUE));
4385       gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
4386       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
4387       gtk_widget_show (menuitem);
4388       
4389       menubar = gtk_menu_bar_new ();
4390       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
4391       gtk_widget_show (menubar);
4392       
4393       menu = create_menu (screen, 2, 10, TRUE);
4394       
4395       menuitem = gtk_menu_item_new_with_label ("Second menu bar");
4396       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
4397       gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
4398       gtk_widget_show (menuitem);
4399       
4400       box2 = gtk_vbox_new (FALSE, 10);
4401       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4402       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4403       gtk_widget_show (box2);
4404       
4405       menu = create_menu (screen, 1, 5, FALSE);
4406       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
4407
4408       menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, accel_group);
4409       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4410       gtk_widget_show (menuitem);
4411       
4412       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
4413       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4414       gtk_widget_show (menuitem);
4415       gtk_widget_add_accelerator (menuitem,
4416                                   "activate",
4417                                   accel_group,
4418                                   GDK_F1,
4419                                   0,
4420                                   GTK_ACCEL_VISIBLE);
4421       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
4422       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4423       gtk_widget_show (menuitem);
4424       gtk_widget_add_accelerator (menuitem,
4425                                   "activate",
4426                                   accel_group,
4427                                   GDK_F2,
4428                                   0,
4429                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
4430       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
4431       gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
4432       gtk_widget_show (menuitem);
4433       gtk_widget_add_accelerator (menuitem,
4434                                   "activate",
4435                                   accel_group,
4436                                   GDK_F2,
4437                                   0,
4438                                   GTK_ACCEL_VISIBLE);
4439       gtk_widget_add_accelerator (menuitem,
4440                                   "activate",
4441                                   accel_group,
4442                                   GDK_F3,
4443                                   0,
4444                                   GTK_ACCEL_VISIBLE);
4445       
4446       optionmenu = gtk_option_menu_new ();
4447       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
4448       gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 3);
4449       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
4450       gtk_widget_show (optionmenu);
4451
4452       separator = gtk_hseparator_new ();
4453       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4454       gtk_widget_show (separator);
4455
4456       box2 = gtk_vbox_new (FALSE, 10);
4457       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4458       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4459       gtk_widget_show (box2);
4460
4461       button = gtk_button_new_with_label ("close");
4462       g_signal_connect_swapped (button, "clicked",
4463                                 G_CALLBACK (gtk_widget_destroy),
4464                                 window);
4465       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4466       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4467       gtk_widget_grab_default (button);
4468       gtk_widget_show (button);
4469     }
4470
4471   if (!GTK_WIDGET_VISIBLE (window))
4472     gtk_widget_show (window);
4473   else
4474     gtk_widget_destroy (window);
4475 }
4476
4477 static void
4478 gtk_ifactory_cb (gpointer             callback_data,
4479                  guint                callback_action,
4480                  GtkWidget           *widget)
4481 {
4482   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
4483 }
4484
4485 /* GdkPixbuf RGBA C-Source image dump */
4486
4487 static const guint8 apple[] = 
4488 { ""
4489   /* Pixbuf magic (0x47646b50) */
4490   "GdkP"
4491   /* length: header (24) + pixel_data (2304) */
4492   "\0\0\11\30"
4493   /* pixdata_type (0x1010002) */
4494   "\1\1\0\2"
4495   /* rowstride (96) */
4496   "\0\0\0`"
4497   /* width (24) */
4498   "\0\0\0\30"
4499   /* height (24) */
4500   "\0\0\0\30"
4501   /* pixel_data: */
4502   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4503   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4504   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4505   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4506   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4507   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4508   "\0\0\0\0\0\0\0\0\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"
4509   "\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"
4510   "\0\0\0\0\0\0\0\0\0\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"
4511   "[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"
4512   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4513   "\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"
4514   "\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"
4515   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4516   "\0\0\0\0\0\0`l\\\20iw_\356y\211h\373x\207g\364~\216i\364u\204e\366gt"
4517   "_\374^jX\241A;-_\0\0\0~\0\0\0\0SM4)SM21B9&\22\320\270\204\1\320\270\204"
4518   "\0\0\0\0\0\0\0\0\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"
4519   "]\212r\200c\366v\205f\371jx_\323_kY\232_kZH^jY\26]iW\211@G9\272:6%j\220"
4520   "\211]\320\221\211`\377\212\203Z\377~xP\377mkE\331]^;|/0\37\21\0\0\0\0"
4521   "\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["
4522   "eT<\216\200Z\203\227\211_\354\234\217c\377\232\217b\362\232\220c\337"
4523   "\243\233k\377\252\241p\377\250\236p\377\241\225h\377\231\214_\377\210"
4524   "\202U\377srI\377[]:\355KO0U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0i"
4525   "v^\200`lY\211^jY\"\0\0\0\0\221\204\\\273\250\233r\377\302\267\224\377"
4526   "\311\300\237\377\272\256\204\377\271\256\177\377\271\257\200\377\267"
4527   "\260\177\377\260\251x\377\250\236l\377\242\225e\377\226\213]\377~zP\377"
4528   "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"
4529   "\0\213\203[v\253\240t\377\334\326\301\377\344\340\317\377\321\312\253"
4530   "\377\303\271\217\377\300\270\213\377\277\267\210\377\272\264\203\377"
4531   "\261\255z\377\250\242n\377\243\232h\377\232\220`\377\210\202V\377nnE"
4532   "\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"
4533   "\234\222e\362\304\274\232\377\337\333\306\377\332\325\273\377\311\302"
4534   "\232\377\312\303\236\377\301\273\216\377\300\271\212\377\270\264\200"
4535   "\377\256\253v\377\246\243n\377\236\232h\377\230\220`\377\213\203V\377"
4536   "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"
4537   "\203Zl\242\234l\377\321\315\260\377\331\324\271\377\320\313\251\377\307"
4538   "\301\232\377\303\276\224\377\300\272\214\377\274\267\206\377\264\260"
4539   "|\377\253\251s\377\244\243n\377\232\230e\377\223\216^\377\207\200U\377"
4540   "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"
4541   "\210\204Y\240\245\237o\377\316\310\253\377\310\303\237\377\304\300\230"
4542   "\377\303\277\225\377\277\272\216\377\274\270\210\377\266\263\200\377"
4543   "\256\254v\377\247\246p\377\237\236j\377\227\226d\377\215\212[\377\203"
4544   "\177T\377qsH\377X]8\377FN.\377DK-\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4545   "\0\0\0\0\207\204X\257\244\240o\377\300\275\231\377\301\275\226\377\274"
4546   "\270\213\377\274\270\214\377\267\264\205\377\264\262\200\377\260\256"
4547   "z\377\251\251s\377\243\244n\377\231\232g\377\220\222`\377\210\211Y\377"
4548   "|}Q\377hlC\377PU3\377CK,\377DL/Y\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
4549   "\0\0\205\204X\220\232\230h\377\261\260\204\377\266\264\212\377\261\260"
4550   "\201\377\263\260\200\377\260\257}\377\256\256x\377\253\254t\377\244\246"
4551   "o\377\233\236i\377\221\224b\377\211\214\\\377\202\204V\377txM\377]b>"
4552   "\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>"
4553   "\215\215_\377\237\237r\377\247\247x\377\247\247t\377\252\252w\377\252"
4554   "\252u\377\252\253t\377\243\246o\377\235\240j\377\223\230c\377\213\217"
4555   "]\377\201\206V\377x}P\377gkD\377RY5\377BI,\377AI,\262\0\0\0\0\0\0\0\0"
4556   "\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"
4557   "\232g\377\234\236i\377\236\241l\377\241\244n\377\240\244m\377\232\237"
4558   "i\377\223\230c\377\212\221]\377\200\210W\377v|P\377jnG\377Za>\377HP2"
4559   "\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"
4560   "\0wzQ6\177\201U\371\206\211Z\377\216\222`\377\220\225a\377\220\225b\377"
4561   "\220\226a\377\213\221_\377\204\213Z\377{\203R\377ryN\377iqH\377^fA\377"
4562   "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"
4563   "\0\0\0\0\0\0\0\0\0\0\0\0ptJTw|Q\371z\177R\377}\202T\377|\203T\377z\200"
4564   "R\377v|O\377pwL\377jpF\377dlB\377`hB\377Yb@\377LT6\377<C*\377\11\12\6"
4565   "\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"
4566   "\0\0\0\0\0\0\0\0\0\0\\`=UgnE\370hnG\377gmE\377djB\377]d>\377[c<\377Y"
4567   "b<\377Zc>\377V_>\377OW8\377BK/\377\16\20\12\377\0\0\0\377\0\0\0\377\0"
4568   "\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"
4569   "\0\1\0\0\0\40\22\24\15\260@D+\377W`;\377OV5\377.3\36\377.3\37\377IP0"
4570   "\377RZ7\377PZ8\3776=&\377\14\15\10\377\0\0\0\377\0\0\0\377\0\0\0\377"
4571   "\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"
4572   "\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"
4573   "\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"
4574   "\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"
4575   "\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"
4576   "\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"
4577   "\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"
4578   "\0\0\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"
4579   "\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"
4580   "\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"};
4581
4582
4583 static void
4584 dump_accels (gpointer             callback_data,
4585              guint                callback_action,
4586              GtkWidget           *widget)
4587 {
4588   gtk_accel_map_save_fd (1 /* stdout */);
4589 }
4590     
4591 static GtkItemFactoryEntry menu_items[] =
4592 {
4593   { "/_File",                  NULL,         NULL,                  0, "<Branch>" },
4594   { "/File/tearoff1",          NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
4595   { "/File/_New",              NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_NEW },
4596   { "/File/_Open",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_OPEN },
4597   { "/File/_Save",             NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
4598   { "/File/Save _As...",       "<control>A", gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_SAVE },
4599   { "/File/_Dump \"_Accels\"",  NULL,        dump_accels,           0 },
4600   { "/File/\\/Test__Escaping/And\\/\n\tWei\\\\rdly",
4601                                 NULL,        gtk_ifactory_cb,       0 },
4602   { "/File/sep1",        NULL,               gtk_ifactory_cb,       0, "<Separator>" },
4603   { "/File/_Quit",       NULL,               gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
4604
4605   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
4606   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
4607   { "/_Preferences/Color/_Red",         NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
4608   { "/_Preferences/Color/_Green",       NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
4609   { "/_Preferences/Color/_Blue",        NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
4610   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
4611   { "/_Preferences/Shape/_Square",      NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
4612   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
4613   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
4614   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
4615   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
4616   { "/_Preferences/Shape/_Image",       NULL, gtk_ifactory_cb, 0, "<ImageItem>", apple },
4617   { "/_Preferences/Coffee",                  NULL, gtk_ifactory_cb, 0, "<CheckItem>" },
4618   { "/_Preferences/Toast",                   NULL, gtk_ifactory_cb, 0, "<CheckItem>" },
4619   { "/_Preferences/Marshmallow Froot Loops", NULL, gtk_ifactory_cb, 0, "<CheckItem>" },
4620
4621   /* For testing deletion of menus */
4622   { "/_Preferences/Should_NotAppear",          NULL, 0,               0, "<Branch>" },
4623   { "/Preferences/ShouldNotAppear/SubItem1",   NULL, gtk_ifactory_cb, 0 },
4624   { "/Preferences/ShouldNotAppear/SubItem2",   NULL, gtk_ifactory_cb, 0 },
4625
4626   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
4627   { "/Help/_Help",       NULL,         gtk_ifactory_cb,       0, "<StockItem>", GTK_STOCK_HELP},
4628   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
4629 };
4630
4631
4632 static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
4633
4634 static void
4635 create_item_factory (GtkWidget *widget)
4636 {
4637   static GtkWidget *window = NULL;
4638   
4639   if (!window)
4640     {
4641       GtkWidget *box1;
4642       GtkWidget *box2;
4643       GtkWidget *separator;
4644       GtkWidget *label;
4645       GtkWidget *button;
4646       GtkAccelGroup *accel_group;
4647       GtkItemFactory *item_factory;
4648       GtkTooltips *tooltips;
4649       
4650       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4651       
4652       gtk_window_set_screen (GTK_WINDOW (window),
4653                              gtk_widget_get_screen (widget));
4654       
4655       g_signal_connect (window, "destroy",
4656                         G_CALLBACK(gtk_widget_destroyed),
4657                         &window);
4658       g_signal_connect (window, "delete-event",
4659                         G_CALLBACK (gtk_true),
4660                         NULL);
4661       
4662       accel_group = gtk_accel_group_new ();
4663       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
4664       g_object_set_data_full (G_OBJECT (window),
4665                               "<main>",
4666                               item_factory,
4667                               g_object_unref);
4668       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
4669       gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
4670       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4671       gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
4672
4673       /* preselect /Preferences/Shape/Oval over the other radios
4674        */
4675       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
4676                                                                                       "/Preferences/Shape/Oval")),
4677                                       TRUE);
4678
4679       /* preselect /Preferences/Coffee
4680        */
4681       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
4682                                                                                       "/Preferences/Coffee")),
4683                                       TRUE);
4684
4685       /* preselect /Preferences/Marshmallow Froot Loops and set it insensitive
4686        */
4687       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
4688                                                                                       "/Preferences/Marshmallow Froot Loops")),
4689                                       TRUE);
4690       gtk_widget_set_sensitive (GTK_WIDGET (gtk_item_factory_get_item (item_factory,
4691                                                                        "/Preferences/Marshmallow Froot Loops")),
4692                                 FALSE);
4693        
4694       /* Test how tooltips (ugh) work on menu items
4695        */
4696       tooltips = gtk_tooltips_new ();
4697       g_object_ref (tooltips);
4698       gtk_object_sink (GTK_OBJECT (tooltips));
4699       g_object_set_data_full (G_OBJECT (window), "testgtk-tooltips",
4700                               tooltips, (GDestroyNotify)g_object_unref);
4701       
4702       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/New"),
4703                             "Create a new file", NULL);
4704       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Open"),
4705                             "Open a file", NULL);
4706       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/File/Save"),
4707                             "Safe file", NULL);
4708       gtk_tooltips_set_tip (tooltips, gtk_item_factory_get_item (item_factory, "/Preferences/Color"),
4709                             "Modify color", NULL);
4710
4711       box1 = gtk_vbox_new (FALSE, 0);
4712       gtk_container_add (GTK_CONTAINER (window), box1);
4713       
4714       gtk_box_pack_start (GTK_BOX (box1),
4715                           gtk_item_factory_get_widget (item_factory, "<main>"),
4716                           FALSE, FALSE, 0);
4717
4718       label = gtk_label_new ("Type\n<alt>\nto start");
4719       gtk_widget_set_size_request (label, 200, 200);
4720       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
4721       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
4722
4723
4724       separator = gtk_hseparator_new ();
4725       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4726
4727
4728       box2 = gtk_vbox_new (FALSE, 10);
4729       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4730       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4731
4732       button = gtk_button_new_with_label ("close");
4733       g_signal_connect_swapped (button, "clicked",
4734                                 G_CALLBACK (gtk_widget_destroy),
4735                                 window);
4736       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4737       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4738       gtk_widget_grab_default (button);
4739
4740       gtk_item_factory_delete_item (item_factory, "/Preferences/ShouldNotAppear");
4741       
4742       gtk_widget_show_all (window);
4743     }
4744   else
4745     gtk_widget_destroy (window);
4746 }
4747
4748 static GtkWidget *
4749 accel_button_new (GtkAccelGroup *accel_group,
4750                   const gchar   *text,
4751                   const gchar   *accel)
4752 {
4753   guint keyval;
4754   GdkModifierType modifiers;
4755   GtkWidget *button;
4756   GtkWidget *label;
4757
4758   gtk_accelerator_parse (accel, &keyval, &modifiers);
4759   g_assert (keyval);
4760
4761   button = gtk_button_new ();
4762   gtk_widget_add_accelerator (button, "activate", accel_group,
4763                               keyval, modifiers, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
4764
4765   label = gtk_accel_label_new (text);
4766   gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), button);
4767   gtk_widget_show (label);
4768   
4769   gtk_container_add (GTK_CONTAINER (button), label);
4770
4771   return button;
4772 }
4773
4774 static void
4775 create_key_lookup (GtkWidget *widget)
4776 {
4777   static GtkWidget *window = NULL;
4778
4779   if (!window)
4780     {
4781       GtkAccelGroup *accel_group = gtk_accel_group_new ();
4782       GtkWidget *button;
4783       
4784       window = gtk_dialog_new_with_buttons ("Key Lookup", NULL, 0,
4785                                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
4786                                             NULL);
4787
4788       gtk_window_set_screen (GTK_WINDOW (window),
4789                              gtk_widget_get_screen (widget));
4790
4791       /* We have to expand it so the accel labels will draw their labels
4792        */
4793       gtk_window_set_default_size (GTK_WINDOW (window), 300, -1);
4794       
4795       gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
4796       
4797       button = gtk_button_new_with_mnemonic ("Button 1 (_a)");
4798       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4799       button = gtk_button_new_with_mnemonic ("Button 2 (_A)");
4800       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4801       button = gtk_button_new_with_mnemonic ("Button 3 (_\321\204)");
4802       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4803       button = gtk_button_new_with_mnemonic ("Button 4 (_\320\244)");
4804       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4805       button = gtk_button_new_with_mnemonic ("Button 6 (_b)");
4806       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4807       button = accel_button_new (accel_group, "Button 7", "<Alt><Shift>b");
4808       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4809       button = accel_button_new (accel_group, "Button 8", "<Alt>d");
4810       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4811       button = accel_button_new (accel_group, "Button 9", "<Alt>Cyrillic_ve");
4812       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4813       button = gtk_button_new_with_mnemonic ("Button 10 (_1)");
4814       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4815       button = gtk_button_new_with_mnemonic ("Button 11 (_!)");
4816       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4817       button = accel_button_new (accel_group, "Button 12", "<Super>a");
4818       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4819       button = accel_button_new (accel_group, "Button 13", "<Hyper>a");
4820       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4821       button = accel_button_new (accel_group, "Button 14", "<Meta>a");
4822       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4823       button = accel_button_new (accel_group, "Button 15", "<Shift><Mod4>b");
4824       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), button, FALSE, FALSE, 0);
4825       
4826       g_object_add_weak_pointer (G_OBJECT (window), (gpointer) &window);
4827       g_signal_connect (window, "response", G_CALLBACK (gtk_object_destroy), NULL);
4828
4829       gtk_widget_show_all (window);
4830     }
4831   else
4832     gtk_widget_destroy (window);
4833 }
4834
4835
4836 /*
4837  create_modal_window
4838  */
4839
4840 static gboolean
4841 cmw_destroy_cb(GtkWidget *widget)
4842 {
4843   /* This is needed to get out of gtk_main */
4844   gtk_main_quit ();
4845
4846   return FALSE;
4847 }
4848
4849 static void
4850 cmw_color (GtkWidget *widget, GtkWidget *parent)
4851 {
4852     GtkWidget *csd;
4853
4854     csd = gtk_color_selection_dialog_new ("This is a modal color selection dialog");
4855
4856     gtk_window_set_screen (GTK_WINDOW (csd), gtk_widget_get_screen (parent));
4857
4858     gtk_color_selection_set_has_palette (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (csd)->colorsel),
4859                                          TRUE);
4860     
4861     /* Set as modal */
4862     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
4863
4864     /* And mark it as a transient dialog */
4865     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
4866     
4867     g_signal_connect (csd, "destroy",
4868                       G_CALLBACK (cmw_destroy_cb), NULL);
4869
4870     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->ok_button,
4871                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
4872     g_signal_connect_swapped (GTK_COLOR_SELECTION_DIALOG (csd)->cancel_button,
4873                              "clicked", G_CALLBACK (gtk_widget_destroy), csd);
4874     
4875     /* wait until destroy calls gtk_main_quit */
4876     gtk_widget_show (csd);    
4877     gtk_main ();
4878 }
4879
4880 static void
4881 cmw_file (GtkWidget *widget, GtkWidget *parent)
4882 {
4883     GtkWidget *fs;
4884
4885     fs = gtk_file_selection_new("This is a modal file selection dialog");
4886
4887     gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
4888
4889     /* Set as modal */
4890     gtk_window_set_modal (GTK_WINDOW(fs),TRUE);
4891
4892     /* And mark it as a transient dialog */
4893     gtk_window_set_transient_for (GTK_WINDOW (fs), GTK_WINDOW (parent));
4894
4895     g_signal_connect (fs, "destroy",
4896                       G_CALLBACK (cmw_destroy_cb), NULL);
4897
4898     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->ok_button,
4899                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
4900     g_signal_connect_swapped (GTK_FILE_SELECTION (fs)->cancel_button,
4901                               "clicked", G_CALLBACK (gtk_widget_destroy), fs);
4902     
4903     /* wait until destroy calls gtk_main_quit */
4904     gtk_widget_show (fs);
4905     
4906     gtk_main();
4907 }
4908
4909
4910 static void
4911 create_modal_window (GtkWidget *widget)
4912 {
4913   GtkWidget *window = NULL;
4914   GtkWidget *box1,*box2;
4915   GtkWidget *frame1;
4916   GtkWidget *btnColor,*btnFile,*btnClose;
4917
4918   /* Create modal window (Here you can use any window descendent )*/
4919   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4920   gtk_window_set_screen (GTK_WINDOW (window),
4921                          gtk_widget_get_screen (widget));
4922
4923   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
4924
4925   /* Set window as modal */
4926   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
4927
4928   /* Create widgets */
4929   box1 = gtk_vbox_new (FALSE,5);
4930   frame1 = gtk_frame_new ("Standard dialogs in modal form");
4931   box2 = gtk_vbox_new (TRUE,5);
4932   btnColor = gtk_button_new_with_label ("Color");
4933   btnFile = gtk_button_new_with_label ("File Selection");
4934   btnClose = gtk_button_new_with_label ("Close");
4935
4936   /* Init widgets */
4937   gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
4938   gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
4939     
4940   /* Pack widgets */
4941   gtk_container_add (GTK_CONTAINER (window), box1);
4942   gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
4943   gtk_container_add (GTK_CONTAINER (frame1), box2);
4944   gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
4945   gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
4946   gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
4947   gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
4948    
4949   /* connect signals */
4950   g_signal_connect_swapped (btnClose, "clicked",
4951                             G_CALLBACK (gtk_widget_destroy), window);
4952
4953   g_signal_connect (window, "destroy",
4954                     G_CALLBACK (cmw_destroy_cb), NULL);
4955   
4956   g_signal_connect (btnColor, "clicked",
4957                     G_CALLBACK (cmw_color), window);
4958   g_signal_connect (btnFile, "clicked",
4959                     G_CALLBACK (cmw_file), window);
4960
4961   /* Show widgets */
4962   gtk_widget_show_all (window);
4963
4964   /* wait until dialog get destroyed */
4965   gtk_main();
4966 }
4967
4968 /*
4969  * GtkMessageDialog
4970  */
4971
4972 static void
4973 make_message_dialog (GdkScreen *screen,
4974                      GtkWidget **dialog,
4975                      GtkMessageType  type,
4976                      GtkButtonsType  buttons,
4977                      guint           default_response)
4978 {
4979   if (*dialog)
4980     {
4981       gtk_widget_destroy (*dialog);
4982
4983       return;
4984     }
4985
4986   *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
4987                                     "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.)");
4988
4989   gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
4990
4991   g_signal_connect_swapped (*dialog,
4992                             "response",
4993                             G_CALLBACK (gtk_widget_destroy),
4994                             *dialog);
4995   
4996   g_signal_connect (*dialog,
4997                     "destroy",
4998                     G_CALLBACK (gtk_widget_destroyed),
4999                     dialog);
5000
5001   gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
5002
5003   gtk_widget_show (*dialog);
5004 }
5005
5006 static void
5007 create_message_dialog (GtkWidget *widget)
5008 {
5009   static GtkWidget *info = NULL;
5010   static GtkWidget *warning = NULL;
5011   static GtkWidget *error = NULL;
5012   static GtkWidget *question = NULL;
5013   GdkScreen *screen = gtk_widget_get_screen (widget);
5014
5015   make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
5016   make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE);
5017   make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
5018   make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_NO);
5019 }
5020
5021 /*
5022  * GtkScrolledWindow
5023  */
5024
5025 static GtkWidget *sw_parent = NULL;
5026 static GtkWidget *sw_float_parent;
5027 static guint sw_destroyed_handler = 0;
5028
5029 static gboolean
5030 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
5031 {
5032   gtk_widget_reparent (scrollwin, sw_parent);
5033   
5034   g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
5035   sw_float_parent = NULL;
5036   sw_parent = NULL;
5037   sw_destroyed_handler = 0;
5038
5039   return FALSE;
5040 }
5041
5042 static void
5043 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
5044 {
5045   gtk_widget_destroy (sw_float_parent);
5046
5047   sw_float_parent = NULL;
5048   sw_parent = NULL;
5049   sw_destroyed_handler = 0;
5050 }
5051
5052 static void
5053 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
5054 {
5055   if (sw_parent)
5056     {
5057       gtk_widget_reparent (scrollwin, sw_parent);
5058       gtk_widget_destroy (sw_float_parent);
5059
5060       g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
5061       sw_float_parent = NULL;
5062       sw_parent = NULL;
5063       sw_destroyed_handler = 0;
5064     }
5065   else
5066     {
5067       sw_parent = scrollwin->parent;
5068       sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5069       gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
5070                              gtk_widget_get_screen (widget));
5071       
5072       gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
5073       
5074       gtk_widget_reparent (scrollwin, sw_float_parent);
5075       gtk_widget_show (sw_float_parent);
5076
5077       sw_destroyed_handler =
5078         g_signal_connect (sw_parent, "destroy",
5079                           G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
5080       g_signal_connect (sw_float_parent, "delete_event",
5081                         G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
5082     }
5083 }
5084
5085 static void
5086 create_scrolled_windows (GtkWidget *widget)
5087 {
5088   static GtkWidget *window;
5089   GtkWidget *scrolled_window;
5090   GtkWidget *table;
5091   GtkWidget *button;
5092   char buffer[32];
5093   int i, j;
5094
5095   if (!window)
5096     {
5097       window = gtk_dialog_new ();
5098
5099       gtk_window_set_screen (GTK_WINDOW (window),
5100                              gtk_widget_get_screen (widget));
5101
5102       g_signal_connect (window, "destroy",
5103                         G_CALLBACK (gtk_widget_destroyed),
5104                         &window);
5105
5106       gtk_window_set_title (GTK_WINDOW (window), "dialog");
5107       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5108
5109
5110       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
5111       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
5112       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
5113                                       GTK_POLICY_AUTOMATIC,
5114                                       GTK_POLICY_AUTOMATIC);
5115       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
5116                           scrolled_window, TRUE, TRUE, 0);
5117       gtk_widget_show (scrolled_window);
5118
5119       table = gtk_table_new (20, 20, FALSE);
5120       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
5121       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
5122       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
5123       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
5124                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
5125       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
5126                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
5127       gtk_widget_show (table);
5128
5129       for (i = 0; i < 20; i++)
5130         for (j = 0; j < 20; j++)
5131           {
5132             sprintf (buffer, "button (%d,%d)\n", i, j);
5133             button = gtk_toggle_button_new_with_label (buffer);
5134             gtk_table_attach_defaults (GTK_TABLE (table), button,
5135                                        i, i+1, j, j+1);
5136             gtk_widget_show (button);
5137           }
5138
5139
5140       button = gtk_button_new_with_label ("Close");
5141       g_signal_connect_swapped (button, "clicked",
5142                                 G_CALLBACK (gtk_widget_destroy),
5143                                 window);
5144       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5145       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
5146                           button, TRUE, TRUE, 0);
5147       gtk_widget_grab_default (button);
5148       gtk_widget_show (button);
5149
5150       button = gtk_button_new_with_label ("Reparent Out");
5151       g_signal_connect (button, "clicked",
5152                         G_CALLBACK (scrolled_windows_remove),
5153                         scrolled_window);
5154       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5155       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
5156                           button, TRUE, TRUE, 0);
5157       gtk_widget_grab_default (button);
5158       gtk_widget_show (button);
5159
5160       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
5161     }
5162
5163   if (!GTK_WIDGET_VISIBLE (window))
5164     gtk_widget_show (window);
5165   else
5166     gtk_widget_destroy (window);
5167 }
5168
5169 /*
5170  * GtkEntry
5171  */
5172
5173 static void
5174 entry_toggle_frame (GtkWidget *checkbutton,
5175                     GtkWidget *entry)
5176 {
5177    gtk_entry_set_has_frame (GTK_ENTRY(entry),
5178                             GTK_TOGGLE_BUTTON(checkbutton)->active);
5179 }
5180
5181 static void
5182 entry_toggle_sensitive (GtkWidget *checkbutton,
5183                         GtkWidget *entry)
5184 {
5185    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
5186 }
5187
5188 static void
5189 entry_props_clicked (GtkWidget *button,
5190                      GObject   *entry)
5191 {
5192   GtkWidget *window = create_prop_editor (entry, 0);
5193
5194   gtk_window_set_title (GTK_WINDOW (window), "Entry Properties");
5195 }
5196
5197 static void
5198 create_entry (GtkWidget *widget)
5199 {
5200   static GtkWidget *window = NULL;
5201   GtkWidget *box1;
5202   GtkWidget *box2;
5203   GtkWidget *hbox;
5204   GtkWidget *has_frame_check;
5205   GtkWidget *sensitive_check;
5206   GtkWidget *entry, *cb;
5207   GtkWidget *button;
5208   GtkWidget *separator;
5209   GList *cbitems = NULL;
5210
5211   if (!window)
5212     {
5213       cbitems = g_list_append(cbitems, "item0");
5214       cbitems = g_list_append(cbitems, "item1 item1");
5215       cbitems = g_list_append(cbitems, "item2 item2 item2");
5216       cbitems = g_list_append(cbitems, "item3 item3 item3 item3");
5217       cbitems = g_list_append(cbitems, "item4 item4 item4 item4 item4");
5218       cbitems = g_list_append(cbitems, "item5 item5 item5 item5 item5 item5");
5219       cbitems = g_list_append(cbitems, "item6 item6 item6 item6 item6");
5220       cbitems = g_list_append(cbitems, "item7 item7 item7 item7");
5221       cbitems = g_list_append(cbitems, "item8 item8 item8");
5222       cbitems = g_list_append(cbitems, "item9 item9");
5223
5224       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5225       gtk_window_set_screen (GTK_WINDOW (window),
5226                              gtk_widget_get_screen (widget));
5227
5228       g_signal_connect (window, "destroy",
5229                         G_CALLBACK (gtk_widget_destroyed),
5230                         &window);
5231
5232       gtk_window_set_title (GTK_WINDOW (window), "entry");
5233       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5234
5235
5236       box1 = gtk_vbox_new (FALSE, 0);
5237       gtk_container_add (GTK_CONTAINER (window), box1);
5238
5239
5240       box2 = gtk_vbox_new (FALSE, 10);
5241       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5242       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5243
5244       hbox = gtk_hbox_new (FALSE, 5);
5245       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
5246       
5247       entry = gtk_entry_new ();
5248       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");
5249       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
5250       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
5251
5252       button = gtk_button_new_with_mnemonic ("_Props");
5253       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
5254       g_signal_connect (button, "clicked",
5255                         G_CALLBACK (entry_props_clicked),
5256                         entry);
5257
5258       cb = gtk_combo_new ();
5259       gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
5260       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(cb)->entry), "hello world \n\n\n foo");
5261       gtk_editable_select_region (GTK_EDITABLE (GTK_COMBO(cb)->entry),
5262                                   0, -1);
5263       gtk_box_pack_start (GTK_BOX (box2), cb, TRUE, TRUE, 0);
5264
5265       sensitive_check = gtk_check_button_new_with_label("Sensitive");
5266       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
5267       g_signal_connect (sensitive_check, "toggled",
5268                         G_CALLBACK (entry_toggle_sensitive), entry);
5269       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
5270
5271       has_frame_check = gtk_check_button_new_with_label("Has Frame");
5272       gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
5273       g_signal_connect (has_frame_check, "toggled",
5274                         G_CALLBACK (entry_toggle_frame), entry);
5275       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
5276       
5277       separator = gtk_hseparator_new ();
5278       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5279
5280       box2 = gtk_vbox_new (FALSE, 10);
5281       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5282       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5283
5284       button = gtk_button_new_with_label ("close");
5285       g_signal_connect_swapped (button, "clicked",
5286                                 G_CALLBACK (gtk_widget_destroy),
5287                                 window);
5288       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5289       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5290       gtk_widget_grab_default (button);
5291     }
5292
5293   if (!GTK_WIDGET_VISIBLE (window))
5294     gtk_widget_show_all (window);
5295   else
5296     gtk_widget_destroy (window);
5297 }
5298
5299 static void
5300 create_expander (GtkWidget *widget)
5301 {
5302   GtkWidget *box1;
5303   GtkWidget *expander;
5304   GtkWidget *hidden;
5305   static GtkWidget *window = NULL;
5306
5307   if (!window)
5308     {
5309       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5310       gtk_window_set_screen (GTK_WINDOW (window),
5311                              gtk_widget_get_screen (widget));
5312       
5313       g_signal_connect (window, "destroy",
5314                         G_CALLBACK (gtk_widget_destroyed),
5315                         &window);
5316       
5317       gtk_window_set_title (GTK_WINDOW (window), "expander");
5318       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5319       
5320       box1 = gtk_vbox_new (FALSE, 0);
5321       gtk_container_add (GTK_CONTAINER (window), box1);
5322       
5323       expander = gtk_expander_new ("The Hidden");
5324       
5325       gtk_box_pack_start (GTK_BOX (box1), expander, TRUE, TRUE, 0);
5326       
5327       hidden = gtk_label_new ("Revealed!");
5328       
5329       gtk_container_add (GTK_CONTAINER (expander), hidden);
5330     }
5331   
5332   if (!GTK_WIDGET_VISIBLE (window))
5333     gtk_widget_show_all (window);
5334   else
5335     gtk_widget_destroy (window);
5336 }
5337
5338
5339 /* GtkEventBox */
5340
5341
5342 static void
5343 event_box_label_pressed (GtkWidget        *widget,
5344                          GdkEventButton   *event,
5345                          gpointer user_data)
5346 {
5347   g_print ("clicked on event box\n");
5348 }
5349
5350 static void
5351 event_box_button_clicked (GtkWidget *widget,
5352                           GtkWidget *button,
5353                           gpointer user_data)
5354 {
5355   g_print ("pushed button\n");
5356 }
5357
5358 static void
5359 event_box_toggle_visible_window (GtkWidget *checkbutton,
5360                                  GtkEventBox *event_box)
5361 {
5362   gtk_event_box_set_visible_window (event_box,
5363                                     GTK_TOGGLE_BUTTON(checkbutton)->active);
5364 }
5365
5366 static void
5367 event_box_toggle_above_child (GtkWidget *checkbutton,
5368                               GtkEventBox *event_box)
5369 {
5370   gtk_event_box_set_above_child (event_box,
5371                                  GTK_TOGGLE_BUTTON(checkbutton)->active);
5372 }
5373
5374 static void
5375 create_event_box (GtkWidget *widget)
5376 {
5377   static GtkWidget *window = NULL;
5378   GtkWidget *box1;
5379   GtkWidget *box2;
5380   GtkWidget *hbox;
5381   GtkWidget *vbox;
5382   GtkWidget *button;
5383   GtkWidget *separator;
5384   GtkWidget *event_box;
5385   GtkWidget *label;
5386   GtkWidget *visible_window_check;
5387   GtkWidget *above_child_check;
5388   GdkColor color;
5389
5390   if (!window)
5391     {
5392       color.red = 0;
5393       color.blue = 65535;
5394       color.green = 0;
5395       
5396       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5397       gtk_window_set_screen (GTK_WINDOW (window),
5398                              gtk_widget_get_screen (widget));
5399
5400       g_signal_connect (window, "destroy",
5401                         G_CALLBACK (gtk_widget_destroyed),
5402                         &window);
5403
5404       gtk_window_set_title (GTK_WINDOW (window), "event box");
5405       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5406
5407       box1 = gtk_vbox_new (FALSE, 0);
5408       gtk_container_add (GTK_CONTAINER (window), box1);
5409       gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &color);
5410
5411       hbox = gtk_hbox_new (FALSE, 0);
5412       gtk_box_pack_start (GTK_BOX (box1), hbox, TRUE, FALSE, 0);
5413       
5414       event_box = gtk_event_box_new ();
5415       gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, FALSE, 0);
5416
5417       vbox = gtk_vbox_new (FALSE, 0);
5418       gtk_container_add (GTK_CONTAINER (event_box), vbox);
5419       g_signal_connect (event_box, "button_press_event",
5420                         G_CALLBACK (event_box_label_pressed),
5421                         NULL);
5422       
5423       label = gtk_label_new ("Click on this label");
5424       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
5425
5426       button = gtk_button_new_with_label ("button in eventbox");
5427       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, FALSE, 0);
5428       g_signal_connect (button, "clicked",
5429                         G_CALLBACK (event_box_button_clicked),
5430                         NULL);
5431       
5432
5433       visible_window_check = gtk_check_button_new_with_label("Visible Window");
5434       gtk_box_pack_start (GTK_BOX (box1), visible_window_check, FALSE, TRUE, 0);
5435       g_signal_connect (visible_window_check, "toggled",
5436                         G_CALLBACK (event_box_toggle_visible_window), event_box);
5437       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visible_window_check), FALSE);
5438       
5439       above_child_check = gtk_check_button_new_with_label("Above Child");
5440       gtk_box_pack_start (GTK_BOX (box1), above_child_check, FALSE, TRUE, 0);
5441       g_signal_connect (above_child_check, "toggled",
5442                         G_CALLBACK (event_box_toggle_above_child), event_box);
5443       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (above_child_check), FALSE);
5444       
5445       separator = gtk_hseparator_new ();
5446       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5447
5448       box2 = gtk_vbox_new (FALSE, 10);
5449       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5450       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5451
5452       button = gtk_button_new_with_label ("close");
5453       g_signal_connect_swapped (button, "clicked",
5454                                 G_CALLBACK (gtk_widget_destroy),
5455                                 window);
5456       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5457       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5458       gtk_widget_grab_default (button);
5459     }
5460
5461   if (!GTK_WIDGET_VISIBLE (window))
5462     gtk_widget_show_all (window);
5463   else
5464     gtk_widget_destroy (window);
5465 }
5466
5467
5468 /*
5469  * GtkSizeGroup
5470  */
5471
5472 #define SIZE_GROUP_INITIAL_SIZE 50
5473
5474 static void
5475 size_group_hsize_changed (GtkSpinButton *spin_button,
5476                           GtkWidget     *button)
5477 {
5478   gtk_widget_set_size_request (GTK_BIN (button)->child,
5479                                gtk_spin_button_get_value_as_int (spin_button),
5480                                -1);
5481 }
5482
5483 static void
5484 size_group_vsize_changed (GtkSpinButton *spin_button,
5485                           GtkWidget     *button)
5486 {
5487   gtk_widget_set_size_request (GTK_BIN (button)->child,
5488                                -1,
5489                                gtk_spin_button_get_value_as_int (spin_button));
5490 }
5491
5492 static GtkWidget *
5493 create_size_group_window (GdkScreen    *screen,
5494                           GtkSizeGroup *master_size_group)
5495 {
5496   GtkWidget *window;
5497   GtkWidget *table;
5498   GtkWidget *main_button;
5499   GtkWidget *button;
5500   GtkWidget *spin_button;
5501   GtkWidget *hbox;
5502   GtkSizeGroup *hgroup1;
5503   GtkSizeGroup *hgroup2;
5504   GtkSizeGroup *vgroup1;
5505   GtkSizeGroup *vgroup2;
5506
5507   window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
5508                                         NULL, 0,
5509                                         GTK_STOCK_CLOSE,
5510                                         GTK_RESPONSE_NONE,
5511                                         NULL);
5512
5513   gtk_window_set_screen (GTK_WINDOW (window), screen);
5514
5515   gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
5516
5517   g_signal_connect (window, "response",
5518                     G_CALLBACK (gtk_widget_destroy),
5519                     NULL);
5520
5521   table = gtk_table_new (2, 2, FALSE);
5522   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), table, TRUE, TRUE, 0);
5523
5524   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
5525   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
5526   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
5527   gtk_widget_set_size_request (table, 250, 250);
5528
5529   hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
5530   hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
5531   vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
5532   vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
5533
5534   main_button = gtk_button_new_with_label ("X");
5535   
5536   gtk_table_attach (GTK_TABLE (table), main_button,
5537                     0, 1,       0, 1,
5538                     GTK_EXPAND, GTK_EXPAND,
5539                     0,          0);
5540   gtk_size_group_add_widget (master_size_group, main_button);
5541   gtk_size_group_add_widget (hgroup1, main_button);
5542   gtk_size_group_add_widget (vgroup1, main_button);
5543   gtk_widget_set_size_request (GTK_BIN (main_button)->child,
5544                                SIZE_GROUP_INITIAL_SIZE,
5545                                SIZE_GROUP_INITIAL_SIZE);
5546
5547   button = gtk_button_new ();
5548   gtk_table_attach (GTK_TABLE (table), button,
5549                     1, 2,       0, 1,
5550                     GTK_EXPAND, GTK_EXPAND,
5551                     0,          0);
5552   gtk_size_group_add_widget (vgroup1, button);
5553   gtk_size_group_add_widget (vgroup2, button);
5554
5555   button = gtk_button_new ();
5556   gtk_table_attach (GTK_TABLE (table), button,
5557                     0, 1,       1, 2,
5558                     GTK_EXPAND, GTK_EXPAND,
5559                     0,          0);
5560   gtk_size_group_add_widget (hgroup1, button);
5561   gtk_size_group_add_widget (hgroup2, button);
5562
5563   button = gtk_button_new ();
5564   gtk_table_attach (GTK_TABLE (table), button,
5565                     1, 2,       1, 2,
5566                     GTK_EXPAND, GTK_EXPAND,
5567                     0,          0);
5568   gtk_size_group_add_widget (hgroup2, button);
5569   gtk_size_group_add_widget (vgroup2, button);
5570
5571   g_object_unref (hgroup1);
5572   g_object_unref (hgroup2);
5573   g_object_unref (vgroup1);
5574   g_object_unref (vgroup2);
5575   
5576   hbox = gtk_hbox_new (FALSE, 5);
5577   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox, FALSE, FALSE, 0);
5578   
5579   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
5580   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
5581   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
5582   g_signal_connect (spin_button, "value_changed",
5583                     G_CALLBACK (size_group_hsize_changed), main_button);
5584
5585   spin_button = gtk_spin_button_new_with_range (1, 100, 1);
5586   gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
5587   gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
5588   g_signal_connect (spin_button, "value_changed",
5589                     G_CALLBACK (size_group_vsize_changed), main_button);
5590
5591   return window;
5592 }
5593
5594 static void
5595 create_size_groups (GtkWidget *widget)
5596 {
5597   static GtkWidget *window1 = NULL;
5598   static GtkWidget *window2 = NULL;
5599   static GtkSizeGroup *master_size_group;
5600
5601   if (!master_size_group)
5602     master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
5603
5604   if (!window1)
5605     {
5606       window1 = create_size_group_window (gtk_widget_get_screen (widget),
5607                                           master_size_group);
5608
5609       g_signal_connect (window1, "destroy",
5610                         G_CALLBACK (gtk_widget_destroyed),
5611                         &window1);
5612     }
5613
5614   if (!window2)
5615     {
5616       window2 = create_size_group_window (gtk_widget_get_screen (widget),
5617                                           master_size_group);
5618
5619       g_signal_connect (window2, "destroy",
5620                         G_CALLBACK (gtk_widget_destroyed),
5621                         &window2);
5622     }
5623
5624   if (GTK_WIDGET_VISIBLE (window1) && GTK_WIDGET_VISIBLE (window2))
5625     {
5626       gtk_widget_destroy (window1);
5627       gtk_widget_destroy (window2);
5628     }
5629   else
5630     {
5631       if (!GTK_WIDGET_VISIBLE (window1))
5632         gtk_widget_show_all (window1);
5633       if (!GTK_WIDGET_VISIBLE (window2))
5634         gtk_widget_show_all (window2);
5635     }
5636 }
5637
5638 /*
5639  * GtkSpinButton
5640  */
5641
5642 static GtkWidget *spinner1;
5643
5644 static void
5645 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
5646 {
5647   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
5648 }
5649
5650 static void
5651 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
5652 {
5653   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
5654 }
5655
5656 static void
5657 change_digits (GtkWidget *widget, GtkSpinButton *spin)
5658 {
5659   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
5660                               gtk_spin_button_get_value_as_int (spin));
5661 }
5662
5663 static void
5664 get_value (GtkWidget *widget, gpointer data)
5665 {
5666   gchar buf[32];
5667   GtkLabel *label;
5668   GtkSpinButton *spin;
5669
5670   spin = GTK_SPIN_BUTTON (spinner1);
5671   label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
5672   if (GPOINTER_TO_INT (data) == 1)
5673     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
5674   else
5675     sprintf (buf, "%0.*f", spin->digits, gtk_spin_button_get_value (spin));
5676   gtk_label_set_text (label, buf);
5677 }
5678
5679 static void
5680 get_spin_value (GtkWidget *widget, gpointer data)
5681 {
5682   gchar *buffer;
5683   GtkLabel *label;
5684   GtkSpinButton *spin;
5685
5686   spin = GTK_SPIN_BUTTON (widget);
5687   label = GTK_LABEL (data);
5688
5689   buffer = g_strdup_printf ("%0.*f", spin->digits,
5690                             gtk_spin_button_get_value (spin));
5691   gtk_label_set_text (label, buffer);
5692
5693   g_free (buffer);
5694 }
5695
5696 static gint
5697 spin_button_time_output_func (GtkSpinButton *spin_button)
5698 {
5699   static gchar buf[6];
5700   gdouble hours;
5701   gdouble minutes;
5702
5703   hours = spin_button->adjustment->value / 60.0;
5704   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
5705   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
5706   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
5707     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
5708   return TRUE;
5709 }
5710
5711 static gint
5712 spin_button_month_input_func (GtkSpinButton *spin_button,
5713                               gdouble       *new_val)
5714 {
5715   gint i;
5716   static gchar *month[12] = { "January", "February", "March", "April",
5717                               "May", "June", "July", "August",
5718                               "September", "October", "November", "December" };
5719   gchar *tmp1, *tmp2;
5720   gboolean found = FALSE;
5721
5722   for (i = 1; i <= 12; i++)
5723     {
5724       tmp1 = g_ascii_strup (month[i - 1], -1);
5725       tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
5726       if (strstr (tmp1, tmp2) == tmp1)
5727         found = TRUE;
5728       g_free (tmp1);
5729       g_free (tmp2);
5730       if (found)
5731         break;
5732     }
5733   if (!found)
5734     {
5735       *new_val = 0.0;
5736       return GTK_INPUT_ERROR;
5737     }
5738   *new_val = (gdouble) i;
5739   return TRUE;
5740 }
5741
5742 static gint
5743 spin_button_month_output_func (GtkSpinButton *spin_button)
5744 {
5745   gint i;
5746   static gchar *month[12] = { "January", "February", "March", "April",
5747                               "May", "June", "July", "August", "September",
5748                               "October", "November", "December" };
5749
5750   for (i = 1; i <= 12; i++)
5751     if (fabs (spin_button->adjustment->value - (double)i) < 1e-5)
5752       {
5753         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
5754           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
5755       }
5756   return TRUE;
5757 }
5758
5759 static gint
5760 spin_button_hex_input_func (GtkSpinButton *spin_button,
5761                             gdouble       *new_val)
5762 {
5763   const gchar *buf;
5764   gchar *err;
5765   gdouble res;
5766
5767   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
5768   res = strtol(buf, &err, 16);
5769   *new_val = res;
5770   if (*err)
5771     return GTK_INPUT_ERROR;
5772   else
5773     return TRUE;
5774 }
5775
5776 static gint
5777 spin_button_hex_output_func (GtkSpinButton *spin_button)
5778 {
5779   static gchar buf[7];
5780   gint val;
5781
5782   val = (gint) spin_button->adjustment->value;
5783   if (fabs (val) < 1e-5)
5784     sprintf (buf, "0x00");
5785   else
5786     sprintf (buf, "0x%.2X", val);
5787   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
5788     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
5789   return TRUE;
5790 }
5791
5792 static void
5793 create_spins (GtkWidget *widget)
5794 {
5795   static GtkWidget *window = NULL;
5796   GtkWidget *frame;
5797   GtkWidget *hbox;
5798   GtkWidget *main_vbox;
5799   GtkWidget *vbox;
5800   GtkWidget *vbox2;
5801   GtkWidget *spinner2;
5802   GtkWidget *spinner;
5803   GtkWidget *button;
5804   GtkWidget *label;
5805   GtkWidget *val_label;
5806   GtkAdjustment *adj;
5807
5808   if (!window)
5809     {
5810       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5811       gtk_window_set_screen (GTK_WINDOW (window),
5812                              gtk_widget_get_screen (widget));
5813       
5814       g_signal_connect (window, "destroy",
5815                         G_CALLBACK (gtk_widget_destroyed),
5816                         &window);
5817       
5818       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
5819       
5820       main_vbox = gtk_vbox_new (FALSE, 5);
5821       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
5822       gtk_container_add (GTK_CONTAINER (window), main_vbox);
5823       
5824       frame = gtk_frame_new ("Not accelerated");
5825       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
5826       
5827       vbox = gtk_vbox_new (FALSE, 0);
5828       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
5829       gtk_container_add (GTK_CONTAINER (frame), vbox);
5830       
5831       /* Time, month, hex spinners */
5832       
5833       hbox = gtk_hbox_new (FALSE, 0);
5834       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
5835       
5836       vbox2 = gtk_vbox_new (FALSE, 0);
5837       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
5838       
5839       label = gtk_label_new ("Time :");
5840       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5841       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
5842       
5843       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
5844       spinner = gtk_spin_button_new (adj, 0, 0);
5845       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
5846       g_signal_connect (spinner,
5847                         "output",
5848                         G_CALLBACK (spin_button_time_output_func),
5849                         NULL);
5850       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
5851       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 5);
5852       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
5853
5854       vbox2 = gtk_vbox_new (FALSE, 0);
5855       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
5856       
5857       label = gtk_label_new ("Month :");
5858       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5859       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
5860       
5861       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
5862                                                   5.0, 0.0);
5863       spinner = gtk_spin_button_new (adj, 0, 0);
5864       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
5865                                          GTK_UPDATE_IF_VALID);
5866       g_signal_connect (spinner,
5867                         "input",
5868                         G_CALLBACK (spin_button_month_input_func),
5869                         NULL);
5870       g_signal_connect (spinner,
5871                         "output",
5872                         G_CALLBACK (spin_button_month_output_func),
5873                         NULL);
5874       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
5875       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 9);
5876       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
5877       
5878       vbox2 = gtk_vbox_new (FALSE, 0);
5879       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
5880
5881       label = gtk_label_new ("Hex :");
5882       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5883       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
5884
5885       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 255, 1, 16, 0);
5886       spinner = gtk_spin_button_new (adj, 0, 0);
5887       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
5888       g_signal_connect (spinner,
5889                         "input",
5890                         G_CALLBACK (spin_button_hex_input_func),
5891                         NULL);
5892       g_signal_connect (spinner,
5893                         "output",
5894                         G_CALLBACK (spin_button_hex_output_func),
5895                         NULL);
5896       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
5897       gtk_entry_set_width_chars (GTK_ENTRY (spinner), 4);
5898       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
5899
5900       frame = gtk_frame_new ("Accelerated");
5901       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
5902   
5903       vbox = gtk_vbox_new (FALSE, 0);
5904       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
5905       gtk_container_add (GTK_CONTAINER (frame), vbox);
5906       
5907       hbox = gtk_hbox_new (FALSE, 0);
5908       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
5909       
5910       vbox2 = gtk_vbox_new (FALSE, 0);
5911       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
5912       
5913       label = gtk_label_new ("Value :");
5914       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5915       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
5916
5917       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
5918                                                   0.5, 100.0, 0.0);
5919       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
5920       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
5921       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
5922
5923       vbox2 = gtk_vbox_new (FALSE, 0);
5924       gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
5925
5926       label = gtk_label_new ("Digits :");
5927       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5928       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
5929
5930       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 15, 1, 1, 0);
5931       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
5932       g_signal_connect (adj, "value_changed",
5933                         G_CALLBACK (change_digits),
5934                         spinner2);
5935       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
5936
5937       hbox = gtk_hbox_new (FALSE, 0);
5938       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
5939
5940       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
5941       g_signal_connect (button, "clicked",
5942                         G_CALLBACK (toggle_snap),
5943                         spinner1);
5944       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
5945       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
5946
5947       button = gtk_check_button_new_with_label ("Numeric only input mode");
5948       g_signal_connect (button, "clicked",
5949                         G_CALLBACK (toggle_numeric),
5950                         spinner1);
5951       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
5952       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
5953
5954       val_label = gtk_label_new ("");
5955
5956       hbox = gtk_hbox_new (FALSE, 0);
5957       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
5958
5959       button = gtk_button_new_with_label ("Value as Int");
5960       g_object_set_data (G_OBJECT (button), "user_data", val_label);
5961       g_signal_connect (button, "clicked",
5962                         G_CALLBACK (get_value),
5963                         GINT_TO_POINTER (1));
5964       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5965
5966       button = gtk_button_new_with_label ("Value as Float");
5967       g_object_set_data (G_OBJECT (button), "user_data", val_label);
5968       g_signal_connect (button, "clicked",
5969                         G_CALLBACK (get_value),
5970                         GINT_TO_POINTER (2));
5971       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5972
5973       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
5974       gtk_label_set_text (GTK_LABEL (val_label), "0");
5975
5976       frame = gtk_frame_new ("Using Convenience Constructor");
5977       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
5978   
5979       hbox = gtk_hbox_new (FALSE, 0);
5980       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5981       gtk_container_add (GTK_CONTAINER (frame), hbox);
5982       
5983       val_label = gtk_label_new ("0.0");
5984
5985       spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
5986       gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
5987       g_signal_connect (spinner, "value_changed",
5988                         G_CALLBACK (get_spin_value), val_label);
5989       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
5990       gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
5991
5992       hbox = gtk_hbox_new (FALSE, 0);
5993       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5994   
5995       button = gtk_button_new_with_label ("Close");
5996       g_signal_connect_swapped (button, "clicked",
5997                                 G_CALLBACK (gtk_widget_destroy),
5998                                 window);
5999       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6000     }
6001
6002   if (!GTK_WIDGET_VISIBLE (window))
6003     gtk_widget_show_all (window);
6004   else
6005     gtk_widget_destroy (window);
6006 }
6007
6008
6009 /*
6010  * Cursors
6011  */
6012
6013 static gint
6014 cursor_expose_event (GtkWidget *widget,
6015                      GdkEvent  *event,
6016                      gpointer   user_data)
6017 {
6018   GtkDrawingArea *darea;
6019   GdkDrawable *drawable;
6020   GdkGC *black_gc;
6021   GdkGC *gray_gc;
6022   GdkGC *white_gc;
6023   guint max_width;
6024   guint max_height;
6025
6026   g_return_val_if_fail (widget != NULL, TRUE);
6027   g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE);
6028
6029   darea = GTK_DRAWING_AREA (widget);
6030   drawable = widget->window;
6031   white_gc = widget->style->white_gc;
6032   gray_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
6033   black_gc = widget->style->black_gc;
6034   max_width = widget->allocation.width;
6035   max_height = widget->allocation.height;
6036
6037   gdk_draw_rectangle (drawable, white_gc,
6038                       TRUE,
6039                       0,
6040                       0,
6041                       max_width,
6042                       max_height / 2);
6043
6044   gdk_draw_rectangle (drawable, black_gc,
6045                       TRUE,
6046                       0,
6047                       max_height / 2,
6048                       max_width,
6049                       max_height / 2);
6050
6051   gdk_draw_rectangle (drawable, gray_gc,
6052                       TRUE,
6053                       max_width / 3,
6054                       max_height / 3,
6055                       max_width / 3,
6056                       max_height / 3);
6057
6058   return TRUE;
6059 }
6060
6061 static void
6062 set_cursor (GtkWidget *spinner,
6063             GtkWidget *widget)
6064 {
6065   guint c;
6066   GdkCursor *cursor;
6067   GtkWidget *label;
6068   GEnumClass *class;
6069   GEnumValue *vals;
6070
6071   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
6072   c &= 0xfe;
6073
6074   label = g_object_get_data (G_OBJECT (spinner), "user_data");
6075   
6076   class = gtk_type_class (GDK_TYPE_CURSOR_TYPE);
6077   vals = class->values;
6078
6079   while (vals && vals->value != c)
6080     vals++;
6081   if (vals)
6082     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
6083   else
6084     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
6085
6086   cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), c);
6087   gdk_window_set_cursor (widget->window, cursor);
6088   gdk_cursor_unref (cursor);
6089 }
6090
6091 static gint
6092 cursor_event (GtkWidget          *widget,
6093               GdkEvent           *event,
6094               GtkSpinButton      *spinner)
6095 {
6096   if ((event->type == GDK_BUTTON_PRESS) &&
6097       ((event->button.button == 1) ||
6098        (event->button.button == 3)))
6099     {
6100       gtk_spin_button_spin (spinner, event->button.button == 1 ?
6101                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
6102       return TRUE;
6103     }
6104
6105   return FALSE;
6106 }
6107
6108 #ifdef GDK_WINDOWING_X11
6109 #include "x11/gdkx.h"
6110
6111 static void
6112 change_cursor_theme (GtkWidget *widget,
6113                      gpointer   data)
6114 {
6115   const gchar *theme;
6116   gint size;
6117   GList *children;
6118
6119   children = gtk_container_get_children (GTK_CONTAINER (data));
6120
6121   theme = gtk_entry_get_text (GTK_ENTRY (children->next->data));
6122   size = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (children->next->next->data));
6123
6124   g_list_free (children);
6125
6126   gdk_x11_display_set_cursor_theme (gtk_widget_get_display (widget),
6127                                     theme, size);
6128 }
6129 #endif
6130
6131
6132 static void
6133 create_cursors (GtkWidget *widget)
6134 {
6135   static GtkWidget *window = NULL;
6136   GtkWidget *frame;
6137   GtkWidget *hbox;
6138   GtkWidget *main_vbox;
6139   GtkWidget *vbox;
6140   GtkWidget *darea;
6141   GtkWidget *spinner;
6142   GtkWidget *button;
6143   GtkWidget *label;
6144   GtkWidget *any;
6145   GtkAdjustment *adj;
6146   GtkWidget *entry;
6147   GtkWidget *size;  
6148
6149   if (!window)
6150     {
6151       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6152       gtk_window_set_screen (GTK_WINDOW (window), 
6153                              gtk_widget_get_screen (widget));
6154       
6155       g_signal_connect (window, "destroy",
6156                         G_CALLBACK (gtk_widget_destroyed),
6157                         &window);
6158       
6159       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
6160       
6161       main_vbox = gtk_vbox_new (FALSE, 5);
6162       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
6163       gtk_container_add (GTK_CONTAINER (window), main_vbox);
6164
6165       vbox =
6166         gtk_widget_new (gtk_vbox_get_type (),
6167                         "GtkBox::homogeneous", FALSE,
6168                         "GtkBox::spacing", 5,
6169                         "GtkContainer::border_width", 10,
6170                         "GtkWidget::parent", main_vbox,
6171                         "GtkWidget::visible", TRUE,
6172                         NULL);
6173
6174 #ifdef GDK_WINDOWING_X11
6175       hbox = gtk_hbox_new (FALSE, 0);
6176       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6177       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6178
6179       label = gtk_label_new ("Cursor Theme : ");
6180       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
6181       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6182
6183       entry = gtk_entry_new ();
6184       gtk_entry_set_text (GTK_ENTRY (entry), "default");
6185       gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
6186
6187       size = gtk_spin_button_new_with_range (1.0, 64.0, 1.0);
6188       gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), 24.0);
6189       gtk_box_pack_start (GTK_BOX (hbox), size, TRUE, TRUE, 0);
6190       
6191       g_signal_connect (entry, "changed", 
6192                         G_CALLBACK (change_cursor_theme), hbox);
6193       g_signal_connect (size, "changed", 
6194                         G_CALLBACK (change_cursor_theme), hbox);
6195 #endif
6196
6197       hbox = gtk_hbox_new (FALSE, 0);
6198       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6199       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6200
6201       label = gtk_label_new ("Cursor Value : ");
6202       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
6203       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6204       
6205       adj = (GtkAdjustment *) gtk_adjustment_new (0,
6206                                                   0, 152,
6207                                                   2,
6208                                                   10, 0);
6209       spinner = gtk_spin_button_new (adj, 0, 0);
6210       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
6211
6212       frame =
6213         gtk_widget_new (gtk_frame_get_type (),
6214                         "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN,
6215                         "GtkFrame::label_xalign", 0.5,
6216                         "GtkFrame::label", "Cursor Area",
6217                         "GtkContainer::border_width", 10,
6218                         "GtkWidget::parent", vbox,
6219                         "GtkWidget::visible", TRUE,
6220                         NULL);
6221
6222       darea = gtk_drawing_area_new ();
6223       gtk_widget_set_size_request (darea, 80, 80);
6224       gtk_container_add (GTK_CONTAINER (frame), darea);
6225       g_signal_connect (darea,
6226                         "expose_event",
6227                         G_CALLBACK (cursor_expose_event),
6228                         NULL);
6229       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
6230       g_signal_connect (darea,
6231                         "button_press_event",
6232                         G_CALLBACK (cursor_event),
6233                         spinner);
6234       gtk_widget_show (darea);
6235
6236       g_signal_connect (spinner, "changed",
6237                         G_CALLBACK (set_cursor),
6238                         darea);
6239
6240       label = gtk_widget_new (GTK_TYPE_LABEL,
6241                               "visible", TRUE,
6242                               "label", "XXX",
6243                               "parent", vbox,
6244                               NULL);
6245       gtk_container_child_set (GTK_CONTAINER (vbox), label,
6246                                "expand", FALSE,
6247                                NULL);
6248       g_object_set_data (G_OBJECT (spinner), "user_data", label);
6249
6250       any =
6251         gtk_widget_new (gtk_hseparator_get_type (),
6252                         "GtkWidget::visible", TRUE,
6253                         NULL);
6254       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
6255   
6256       hbox = gtk_hbox_new (FALSE, 0);
6257       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
6258       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
6259
6260       button = gtk_button_new_with_label ("Close");
6261       g_signal_connect_swapped (button, "clicked",
6262                                 G_CALLBACK (gtk_widget_destroy),
6263                                 window);
6264       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6265
6266       gtk_widget_show_all (window);
6267
6268       set_cursor (spinner, darea);
6269     }
6270   else
6271     gtk_widget_destroy (window);
6272 }
6273
6274 /*
6275  * GtkList
6276  */
6277
6278 static void
6279 list_add (GtkWidget *widget,
6280           GtkWidget *list)
6281 {
6282   static int i = 1;
6283   gchar buffer[64];
6284   GtkWidget *list_item;
6285   GtkContainer *container;
6286
6287   container = GTK_CONTAINER (list);
6288
6289   sprintf (buffer, "added item %d", i++);
6290   list_item = gtk_list_item_new_with_label (buffer);
6291   gtk_widget_show (list_item);
6292
6293   gtk_container_add (container, list_item);
6294 }
6295
6296 static void
6297 list_remove (GtkWidget *widget,
6298              GtkList   *list)
6299 {
6300   GList *clear_list = NULL;
6301   GList *sel_row = NULL;
6302   GList *work = NULL;
6303
6304   if (list->selection_mode == GTK_SELECTION_EXTENDED)
6305     {
6306       GtkWidget *item;
6307
6308       item = GTK_CONTAINER (list)->focus_child;
6309       if (!item && list->selection)
6310         item = list->selection->data;
6311
6312       if (item)
6313         {
6314           work = g_list_find (list->children, item);
6315           for (sel_row = work; sel_row; sel_row = sel_row->next)
6316             if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
6317               break;
6318
6319           if (!sel_row)
6320             {
6321               for (sel_row = work; sel_row; sel_row = sel_row->prev)
6322                 if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
6323                   break;
6324             }
6325         }
6326     }
6327
6328   for (work = list->selection; work; work = work->next)
6329     clear_list = g_list_prepend (clear_list, work->data);
6330
6331   clear_list = g_list_reverse (clear_list);
6332   gtk_list_remove_items (GTK_LIST (list), clear_list);
6333   g_list_free (clear_list);
6334
6335   if (list->selection_mode == GTK_SELECTION_EXTENDED && sel_row)
6336     gtk_list_select_child (list, GTK_WIDGET(sel_row->data));
6337 }
6338
6339 static void
6340 list_clear (GtkWidget *widget,
6341             GtkWidget *list)
6342 {
6343   gtk_list_clear_items (GTK_LIST (list), 0, -1);
6344 }
6345
6346 static gchar *selection_mode_items[] =
6347 {
6348   "Single",
6349   "Browse",
6350   "Multiple"
6351 };
6352
6353 static const GtkSelectionMode selection_modes[] = {
6354   GTK_SELECTION_SINGLE,
6355   GTK_SELECTION_BROWSE,
6356   GTK_SELECTION_MULTIPLE
6357 };
6358
6359 static GtkWidget *list_omenu;
6360
6361 static void 
6362 list_toggle_sel_mode (GtkWidget *widget, gpointer data)
6363 {
6364   GtkList *list;
6365   gint i;
6366
6367   list = GTK_LIST (data);
6368
6369   if (!GTK_WIDGET_MAPPED (widget))
6370     return;
6371
6372   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6373
6374   gtk_list_set_selection_mode (list, selection_modes[i]);
6375 }
6376
6377 static void
6378 create_list (GtkWidget *widget)
6379 {
6380   static GtkWidget *window = NULL;
6381
6382   if (!window)
6383     {
6384       GtkWidget *cbox;
6385       GtkWidget *vbox;
6386       GtkWidget *hbox;
6387       GtkWidget *label;
6388       GtkWidget *scrolled_win;
6389       GtkWidget *list;
6390       GtkWidget *button;
6391       GtkWidget *separator;
6392       FILE *infile;
6393
6394       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6395
6396       gtk_window_set_screen (GTK_WINDOW (window),
6397                              gtk_widget_get_screen (widget));
6398
6399       g_signal_connect (window, "destroy",
6400                         G_CALLBACK (gtk_widget_destroyed),
6401                         &window);
6402
6403       gtk_window_set_title (GTK_WINDOW (window), "list");
6404       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6405
6406       vbox = gtk_vbox_new (FALSE, 0);
6407       gtk_container_add (GTK_CONTAINER (window), vbox);
6408
6409       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6410       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
6411       gtk_widget_set_size_request (scrolled_win, -1, 300);
6412       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6413       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6414                                       GTK_POLICY_AUTOMATIC,
6415                                       GTK_POLICY_AUTOMATIC);
6416
6417       list = gtk_list_new ();
6418       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_SINGLE);
6419       gtk_scrolled_window_add_with_viewport
6420         (GTK_SCROLLED_WINDOW (scrolled_win), list);
6421       gtk_container_set_focus_vadjustment
6422         (GTK_CONTAINER (list),
6423          gtk_scrolled_window_get_vadjustment
6424          (GTK_SCROLLED_WINDOW (scrolled_win)));
6425       gtk_container_set_focus_hadjustment
6426         (GTK_CONTAINER (list),
6427          gtk_scrolled_window_get_hadjustment
6428          (GTK_SCROLLED_WINDOW (scrolled_win)));
6429
6430       if ((infile = fopen("../gtk/gtkenums.h", "r")))
6431         {
6432           char buffer[256];
6433           char *pos;
6434           GtkWidget *item;
6435
6436           while (fgets (buffer, 256, infile))
6437             {
6438               if ((pos = strchr (buffer, '\n')))
6439                 *pos = 0;
6440               item = gtk_list_item_new_with_label (buffer);
6441               gtk_container_add (GTK_CONTAINER (list), item);
6442             }
6443           
6444           fclose (infile);
6445         }
6446
6447
6448       hbox = gtk_hbox_new (TRUE, 5);
6449       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6450       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6451
6452       button = gtk_button_new_with_label ("Insert Row");
6453       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6454       g_signal_connect (button, "clicked",
6455                         G_CALLBACK (list_add),
6456                         list);
6457
6458       button = gtk_button_new_with_label ("Clear List");
6459       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6460       g_signal_connect (button, "clicked",
6461                         G_CALLBACK (list_clear),
6462                         list);
6463
6464       button = gtk_button_new_with_label ("Remove Selection");
6465       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6466       g_signal_connect (button, "clicked",
6467                         G_CALLBACK (list_remove),
6468                         list);
6469
6470       cbox = gtk_hbox_new (FALSE, 0);
6471       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
6472
6473       hbox = gtk_hbox_new (FALSE, 5);
6474       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6475       gtk_box_pack_start (GTK_BOX (cbox), hbox, TRUE, FALSE, 0);
6476
6477       label = gtk_label_new ("Selection Mode :");
6478       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6479
6480       list_omenu = build_option_menu (selection_mode_items, 3, 3, 
6481                                       list_toggle_sel_mode,
6482                                       list);
6483       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
6484
6485       separator = gtk_hseparator_new ();
6486       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
6487
6488       cbox = gtk_hbox_new (FALSE, 0);
6489       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
6490
6491       button = gtk_button_new_with_label ("close");
6492       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
6493       gtk_box_pack_start (GTK_BOX (cbox), button, TRUE, TRUE, 0);
6494       g_signal_connect_swapped (button, "clicked",
6495                                 G_CALLBACK (gtk_widget_destroy),
6496                                 window);
6497
6498       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6499       gtk_widget_grab_default (button);
6500     }
6501
6502   if (!GTK_WIDGET_VISIBLE (window))
6503     gtk_widget_show_all (window);
6504   else
6505     gtk_widget_destroy (window);
6506 }
6507
6508 /*
6509  * GtkCList
6510  */
6511
6512 static char * book_open_xpm[] = {
6513 "16 16 4 1",
6514 "       c None s None",
6515 ".      c black",
6516 "X      c #808080",
6517 "o      c white",
6518 "                ",
6519 "  ..            ",
6520 " .Xo.    ...    ",
6521 " .Xoo. ..oo.    ",
6522 " .Xooo.Xooo...  ",
6523 " .Xooo.oooo.X.  ",
6524 " .Xooo.Xooo.X.  ",
6525 " .Xooo.oooo.X.  ",
6526 " .Xooo.Xooo.X.  ",
6527 " .Xooo.oooo.X.  ",
6528 "  .Xoo.Xoo..X.  ",
6529 "   .Xo.o..ooX.  ",
6530 "    .X..XXXXX.  ",
6531 "    ..X.......  ",
6532 "     ..         ",
6533 "                "};
6534
6535 static char * book_closed_xpm[] = {
6536 "16 16 6 1",
6537 "       c None s None",
6538 ".      c black",
6539 "X      c red",
6540 "o      c yellow",
6541 "O      c #808080",
6542 "#      c white",
6543 "                ",
6544 "       ..       ",
6545 "     ..XX.      ",
6546 "   ..XXXXX.     ",
6547 " ..XXXXXXXX.    ",
6548 ".ooXXXXXXXXX.   ",
6549 "..ooXXXXXXXXX.  ",
6550 ".X.ooXXXXXXXXX. ",
6551 ".XX.ooXXXXXX..  ",
6552 " .XX.ooXXX..#O  ",
6553 "  .XX.oo..##OO. ",
6554 "   .XX..##OO..  ",
6555 "    .X.#OO..    ",
6556 "     ..O..      ",
6557 "      ..        ",
6558 "                "};
6559
6560 static char * mini_page_xpm[] = {
6561 "16 16 4 1",
6562 "       c None s None",
6563 ".      c black",
6564 "X      c white",
6565 "o      c #808080",
6566 "                ",
6567 "   .......      ",
6568 "   .XXXXX..     ",
6569 "   .XoooX.X.    ",
6570 "   .XXXXX....   ",
6571 "   .XooooXoo.o  ",
6572 "   .XXXXXXXX.o  ",
6573 "   .XooooooX.o  ",
6574 "   .XXXXXXXX.o  ",
6575 "   .XooooooX.o  ",
6576 "   .XXXXXXXX.o  ",
6577 "   .XooooooX.o  ",
6578 "   .XXXXXXXX.o  ",
6579 "   ..........o  ",
6580 "    oooooooooo  ",
6581 "                "};
6582
6583 static char * gtk_mini_xpm[] = {
6584 "15 20 17 1",
6585 "       c None",
6586 ".      c #14121F",
6587 "+      c #278828",
6588 "@      c #9B3334",
6589 "#      c #284C72",
6590 "$      c #24692A",
6591 "%      c #69282E",
6592 "&      c #37C539",
6593 "*      c #1D2F4D",
6594 "=      c #6D7076",
6595 "-      c #7D8482",
6596 ";      c #E24A49",
6597 ">      c #515357",
6598 ",      c #9B9C9B",
6599 "'      c #2FA232",
6600 ")      c #3CE23D",
6601 "!      c #3B6CCB",
6602 "               ",
6603 "      ***>     ",
6604 "    >.*!!!*    ",
6605 "   ***....#*=  ",
6606 "  *!*.!!!**!!# ",
6607 " .!!#*!#*!!!!# ",
6608 " @%#!.##.*!!$& ",
6609 " @;%*!*.#!#')) ",
6610 " @;;@%!!*$&)'' ",
6611 " @%.%@%$'&)$+' ",
6612 " @;...@$'*'*)+ ",
6613 " @;%..@$+*.')$ ",
6614 " @;%%;;$+..$)# ",
6615 " @;%%;@$$$'.$# ",
6616 " %;@@;;$$+))&* ",
6617 "  %;;;@+$&)&*  ",
6618 "   %;;@'))+>   ",
6619 "    %;@'&#     ",
6620 "     >%$$      ",
6621 "      >=       "};
6622
6623 #define TESTGTK_CLIST_COLUMNS 12
6624 static gint clist_rows = 0;
6625 static GtkWidget *clist_omenu;
6626
6627 static void
6628 add1000_clist (GtkWidget *widget, gpointer data)
6629 {
6630   gint i, row;
6631   char text[TESTGTK_CLIST_COLUMNS][50];
6632   char *texts[TESTGTK_CLIST_COLUMNS];
6633   GdkBitmap *mask;
6634   GdkPixmap *pixmap;
6635   GtkCList  *clist;
6636
6637   clist = GTK_CLIST (data);
6638
6639   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
6640                                          &mask, 
6641                                          &GTK_WIDGET (data)->style->white,
6642                                          gtk_mini_xpm);
6643
6644   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
6645     {
6646       texts[i] = text[i];
6647       sprintf (text[i], "Column %d", i);
6648     }
6649   
6650   texts[3] = NULL;
6651   sprintf (text[1], "Right");
6652   sprintf (text[2], "Center");
6653   
6654   gtk_clist_freeze (GTK_CLIST (data));
6655   for (i = 0; i < 1000; i++)
6656     {
6657       sprintf (text[0], "CListRow %d", rand() % 10000);
6658       row = gtk_clist_append (clist, texts);
6659       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
6660     }
6661
6662   gtk_clist_thaw (GTK_CLIST (data));
6663
6664   g_object_unref (pixmap);
6665   g_object_unref (mask);
6666 }
6667
6668 static void
6669 add10000_clist (GtkWidget *widget, gpointer data)
6670 {
6671   gint i;
6672   char text[TESTGTK_CLIST_COLUMNS][50];
6673   char *texts[TESTGTK_CLIST_COLUMNS];
6674
6675   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
6676     {
6677       texts[i] = text[i];
6678       sprintf (text[i], "Column %d", i);
6679     }
6680   
6681   sprintf (text[1], "Right");
6682   sprintf (text[2], "Center");
6683   
6684   gtk_clist_freeze (GTK_CLIST (data));
6685   for (i = 0; i < 10000; i++)
6686     {
6687       sprintf (text[0], "CListRow %d", rand() % 10000);
6688       gtk_clist_append (GTK_CLIST (data), texts);
6689     }
6690   gtk_clist_thaw (GTK_CLIST (data));
6691 }
6692
6693 void
6694 clear_clist (GtkWidget *widget, gpointer data)
6695 {
6696   gtk_clist_clear (GTK_CLIST (data));
6697   clist_rows = 0;
6698 }
6699
6700 void clist_remove_selection (GtkWidget *widget, GtkCList *clist)
6701 {
6702   gtk_clist_freeze (clist);
6703
6704   while (clist->selection)
6705     {
6706       gint row;
6707
6708       clist_rows--;
6709       row = GPOINTER_TO_INT (clist->selection->data);
6710
6711       gtk_clist_remove (clist, row);
6712
6713       if (clist->selection_mode == GTK_SELECTION_BROWSE)
6714         break;
6715     }
6716
6717   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
6718       clist->focus_row >= 0)
6719     gtk_clist_select_row (clist, clist->focus_row, -1);
6720
6721   gtk_clist_thaw (clist);
6722 }
6723
6724 void toggle_title_buttons (GtkWidget *widget, GtkCList *clist)
6725 {
6726   if (GTK_TOGGLE_BUTTON (widget)->active)
6727     gtk_clist_column_titles_show (clist);
6728   else
6729     gtk_clist_column_titles_hide (clist);
6730 }
6731
6732 void toggle_reorderable (GtkWidget *widget, GtkCList *clist)
6733 {
6734   gtk_clist_set_reorderable (clist, GTK_TOGGLE_BUTTON (widget)->active);
6735 }
6736
6737 static void
6738 insert_row_clist (GtkWidget *widget, gpointer data)
6739 {
6740   static char *text[] =
6741   {
6742     "This", "is an", "inserted", "row.",
6743     "This", "is an", "inserted", "row.",
6744     "This", "is an", "inserted", "row."
6745   };
6746
6747   static GtkStyle *style1 = NULL;
6748   static GtkStyle *style2 = NULL;
6749   static GtkStyle *style3 = NULL;
6750   gint row;
6751   
6752   if (GTK_CLIST (data)->focus_row >= 0)
6753     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
6754                             text);
6755   else
6756     row = gtk_clist_prepend (GTK_CLIST (data), text);
6757
6758   if (!style1)
6759     {
6760       GdkColor col1;
6761       GdkColor col2;
6762
6763       col1.red   = 0;
6764       col1.green = 56000;
6765       col1.blue  = 0;
6766       col2.red   = 32000;
6767       col2.green = 0;
6768       col2.blue  = 56000;
6769
6770       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
6771       style1->base[GTK_STATE_NORMAL] = col1;
6772       style1->base[GTK_STATE_SELECTED] = col2;
6773
6774       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
6775       style2->fg[GTK_STATE_NORMAL] = col1;
6776       style2->fg[GTK_STATE_SELECTED] = col2;
6777
6778       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
6779       style3->fg[GTK_STATE_NORMAL] = col1;
6780       style3->base[GTK_STATE_NORMAL] = col2;
6781       pango_font_description_free (style3->font_desc);
6782       style3->font_desc = pango_font_description_from_string ("courier 12");
6783     }
6784
6785   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
6786   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
6787   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
6788
6789   clist_rows++;
6790 }
6791
6792 static void
6793 clist_warning_test (GtkWidget *button,
6794                     GtkWidget *clist)
6795 {
6796   GtkWidget *child;
6797   static gboolean add_remove = FALSE;
6798
6799   add_remove = !add_remove;
6800
6801   child = gtk_label_new ("Test");
6802   g_object_ref (child);
6803   gtk_object_sink (GTK_OBJECT (child));
6804
6805   if (add_remove)
6806     gtk_container_add (GTK_CONTAINER (clist), child);
6807   else
6808     {
6809       child->parent = clist;
6810       gtk_container_remove (GTK_CONTAINER (clist), child);
6811       child->parent = NULL;
6812     }
6813
6814   gtk_widget_destroy (child);
6815   gtk_widget_unref (child);
6816 }
6817
6818 static void
6819 undo_selection (GtkWidget *button, GtkCList *clist)
6820 {
6821   gtk_clist_undo_selection (clist);
6822 }
6823
6824 static void 
6825 clist_toggle_sel_mode (GtkWidget *widget, gpointer data)
6826 {
6827   GtkCList *clist;
6828   gint i;
6829
6830   clist = GTK_CLIST (data);
6831
6832   if (!GTK_WIDGET_MAPPED (widget))
6833     return;
6834
6835   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6836
6837   gtk_clist_set_selection_mode (clist, selection_modes[i]);
6838 }
6839
6840 static void 
6841 clist_click_column (GtkCList *clist, gint column, gpointer data)
6842 {
6843   if (column == 4)
6844     gtk_clist_set_column_visibility (clist, column, FALSE);
6845   else if (column == clist->sort_column)
6846     {
6847       if (clist->sort_type == GTK_SORT_ASCENDING)
6848         clist->sort_type = GTK_SORT_DESCENDING;
6849       else
6850         clist->sort_type = GTK_SORT_ASCENDING;
6851     }
6852   else
6853     gtk_clist_set_sort_column (clist, column);
6854
6855   gtk_clist_sort (clist);
6856 }
6857
6858 static void
6859 create_clist (GtkWidget *widget)
6860 {
6861   gint i;
6862   static GtkWidget *window = NULL;
6863
6864   static char *titles[] =
6865   {
6866     "auto resize", "not resizeable", "max width 100", "min width 50",
6867     "hide column", "Title 5", "Title 6", "Title 7",
6868     "Title 8",  "Title 9",  "Title 10", "Title 11"
6869   };
6870
6871   char text[TESTGTK_CLIST_COLUMNS][50];
6872   char *texts[TESTGTK_CLIST_COLUMNS];
6873
6874   GtkWidget *vbox;
6875   GtkWidget *hbox;
6876   GtkWidget *clist;
6877   GtkWidget *button;
6878   GtkWidget *separator;
6879   GtkWidget *scrolled_win;
6880   GtkWidget *check;
6881
6882   GtkWidget *undo_button;
6883   GtkWidget *label;
6884
6885   GtkStyle *style;
6886   GdkColor col1;
6887   GdkColor col2;
6888
6889   if (!window)
6890     {
6891       clist_rows = 0;
6892       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6893       gtk_window_set_screen (GTK_WINDOW (window), 
6894                              gtk_widget_get_screen (widget));
6895
6896       g_signal_connect (window, "destroy",
6897                         G_CALLBACK (gtk_widget_destroyed), &window);
6898
6899       gtk_window_set_title (GTK_WINDOW (window), "clist");
6900       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6901
6902       vbox = gtk_vbox_new (FALSE, 0);
6903       gtk_container_add (GTK_CONTAINER (window), vbox);
6904
6905       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6906       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
6907       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6908                                       GTK_POLICY_AUTOMATIC, 
6909                                       GTK_POLICY_AUTOMATIC);
6910
6911       /* create GtkCList here so we have a pointer to throw at the 
6912        * button callbacks -- more is done with it later */
6913       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
6914       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
6915       g_signal_connect (clist, "click_column",
6916                         G_CALLBACK (clist_click_column), NULL);
6917
6918       /* control buttons */
6919       hbox = gtk_hbox_new (FALSE, 5);
6920       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6921       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
6922
6923       button = gtk_button_new_with_label ("Insert Row");
6924       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6925       g_signal_connect (button, "clicked",
6926                         G_CALLBACK (insert_row_clist), clist);
6927
6928       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
6929       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6930       g_signal_connect (button, "clicked",
6931                         G_CALLBACK (add1000_clist), clist);
6932
6933       button = gtk_button_new_with_label ("Add 10,000 Rows");
6934       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6935       g_signal_connect (button, "clicked",
6936                         G_CALLBACK (add10000_clist), clist);
6937
6938       /* second layer of buttons */
6939       hbox = gtk_hbox_new (FALSE, 5);
6940       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6941       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
6942
6943       button = gtk_button_new_with_label ("Clear List");
6944       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6945       g_signal_connect (button, "clicked",
6946                         G_CALLBACK (clear_clist), clist);
6947
6948       button = gtk_button_new_with_label ("Remove Selection");
6949       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6950       g_signal_connect (button, "clicked",
6951                         G_CALLBACK (clist_remove_selection), clist);
6952
6953       undo_button = gtk_button_new_with_label ("Undo Selection");
6954       gtk_box_pack_start (GTK_BOX (hbox), undo_button, TRUE, TRUE, 0);
6955       g_signal_connect (undo_button, "clicked",
6956                         G_CALLBACK (undo_selection), clist);
6957
6958       button = gtk_button_new_with_label ("Warning Test");
6959       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6960       g_signal_connect (button, "clicked",
6961                         G_CALLBACK (clist_warning_test), clist);
6962
6963       /* third layer of buttons */
6964       hbox = gtk_hbox_new (FALSE, 5);
6965       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6966       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
6967
6968       check = gtk_check_button_new_with_label ("Show Title Buttons");
6969       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
6970       g_signal_connect (check, "clicked",
6971                         G_CALLBACK (toggle_title_buttons), clist);
6972       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
6973
6974       check = gtk_check_button_new_with_label ("Reorderable");
6975       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
6976       g_signal_connect (check, "clicked",
6977                         G_CALLBACK (toggle_reorderable), clist);
6978       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
6979
6980       label = gtk_label_new ("Selection Mode :");
6981       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6982
6983       clist_omenu = build_option_menu (selection_mode_items, 3, 3, 
6984                                        clist_toggle_sel_mode,
6985                                        clist);
6986       gtk_box_pack_start (GTK_BOX (hbox), clist_omenu, FALSE, TRUE, 0);
6987
6988       /* 
6989        * the rest of the clist configuration
6990        */
6991
6992       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6993       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
6994       gtk_widget_set_size_request (clist, -1, 300);
6995
6996       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
6997         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
6998
6999       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
7000       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
7001       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
7002       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
7003       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
7004       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
7005                                           GTK_JUSTIFY_RIGHT);
7006       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
7007                                           GTK_JUSTIFY_CENTER);
7008       
7009       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
7010         {
7011           texts[i] = text[i];
7012           sprintf (text[i], "Column %d", i);
7013         }
7014
7015       sprintf (text[1], "Right");
7016       sprintf (text[2], "Center");
7017
7018       col1.red   = 56000;
7019       col1.green = 0;
7020       col1.blue  = 0;
7021       col2.red   = 0;
7022       col2.green = 56000;
7023       col2.blue  = 32000;
7024
7025       style = gtk_style_new ();
7026       style->fg[GTK_STATE_NORMAL] = col1;
7027       style->base[GTK_STATE_NORMAL] = col2;
7028
7029       pango_font_description_set_size (style->font_desc, 14 * PANGO_SCALE);
7030       pango_font_description_set_weight (style->font_desc, PANGO_WEIGHT_BOLD);
7031
7032       for (i = 0; i < 10; i++)
7033         {
7034           sprintf (text[0], "CListRow %d", clist_rows++);
7035           gtk_clist_append (GTK_CLIST (clist), texts);
7036
7037           switch (i % 4)
7038             {
7039             case 2:
7040               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
7041               break;
7042             default:
7043               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
7044               break;
7045             }
7046         }
7047
7048       gtk_style_unref (style);
7049       
7050       separator = gtk_hseparator_new ();
7051       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
7052
7053       hbox = gtk_hbox_new (FALSE, 0);
7054       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
7055
7056       button = gtk_button_new_with_label ("close");
7057       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
7058       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7059       g_signal_connect_swapped (button, "clicked",
7060                                 G_CALLBACK (gtk_widget_destroy),
7061                                 window);
7062
7063       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7064       gtk_widget_grab_default (button);
7065     }
7066
7067   if (!GTK_WIDGET_VISIBLE (window))
7068     gtk_widget_show_all (window);
7069   else
7070     {
7071       clist_rows = 0;
7072       gtk_widget_destroy (window);
7073     }
7074 }
7075
7076 /*
7077  * GtkCTree
7078  */
7079
7080 typedef struct 
7081 {
7082   GdkPixmap *pixmap1;
7083   GdkPixmap *pixmap2;
7084   GdkPixmap *pixmap3;
7085   GdkBitmap *mask1;
7086   GdkBitmap *mask2;
7087   GdkBitmap *mask3;
7088 } CTreePixmaps;
7089
7090 static gint books = 0;
7091 static gint pages = 0;
7092
7093 static GtkWidget *book_label;
7094 static GtkWidget *page_label;
7095 static GtkWidget *sel_label;
7096 static GtkWidget *vis_label;
7097 static GtkWidget *omenu1;
7098 static GtkWidget *omenu2;
7099 static GtkWidget *omenu3;
7100 static GtkWidget *omenu4;
7101 static GtkWidget *spin1;
7102 static GtkWidget *spin2;
7103 static GtkWidget *spin3;
7104 static gint line_style;
7105
7106
7107 static CTreePixmaps *
7108 get_ctree_pixmaps (GtkCTree *ctree)
7109 {
7110   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (ctree));
7111   CTreePixmaps *pixmaps = g_object_get_data (G_OBJECT (screen), "ctree-pixmaps");
7112
7113   if (!pixmaps)
7114     {
7115       GdkColormap *colormap = gdk_screen_get_rgb_colormap (screen);
7116       pixmaps = g_new (CTreePixmaps, 1);
7117       
7118       pixmaps->pixmap1 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
7119                                                                 &pixmaps->mask1, 
7120                                                                 NULL, book_closed_xpm);
7121       pixmaps->pixmap2 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
7122                                                                 &pixmaps->mask2, 
7123                                                                 NULL, book_open_xpm);
7124       pixmaps->pixmap3 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
7125                                                                 &pixmaps->mask3,
7126                                                                 NULL, mini_page_xpm);
7127       
7128       g_object_set_data (G_OBJECT (screen), "ctree-pixmaps", pixmaps);
7129     }
7130
7131   return pixmaps;
7132 }
7133
7134 void after_press (GtkCTree *ctree, gpointer data)
7135 {
7136   char buf[80];
7137
7138   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
7139   gtk_label_set_text (GTK_LABEL (sel_label), buf);
7140
7141   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
7142   gtk_label_set_text (GTK_LABEL (vis_label), buf);
7143
7144   sprintf (buf, "%d", books);
7145   gtk_label_set_text (GTK_LABEL (book_label), buf);
7146
7147   sprintf (buf, "%d", pages);
7148   gtk_label_set_text (GTK_LABEL (page_label), buf);
7149 }
7150
7151 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
7152                  GtkCTreeNode *sibling, gpointer data)
7153 {
7154   char *source;
7155   char *target1;
7156   char *target2;
7157
7158   gtk_ctree_get_node_info (ctree, child, &source, 
7159                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
7160   if (parent)
7161     gtk_ctree_get_node_info (ctree, parent, &target1, 
7162                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
7163   if (sibling)
7164     gtk_ctree_get_node_info (ctree, sibling, &target2, 
7165                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
7166
7167   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
7168            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
7169 }
7170
7171 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
7172 {
7173   if (GTK_CTREE_ROW (list)->is_leaf)
7174     pages--;
7175   else
7176     books--;
7177 }
7178
7179 void expand_all (GtkWidget *widget, GtkCTree *ctree)
7180 {
7181   gtk_ctree_expand_recursive (ctree, NULL);
7182   after_press (ctree, NULL);
7183 }
7184
7185 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
7186 {
7187   gtk_ctree_collapse_recursive (ctree, NULL);
7188   after_press (ctree, NULL);
7189 }
7190
7191 void select_all (GtkWidget *widget, GtkCTree *ctree)
7192 {
7193   gtk_ctree_select_recursive (ctree, NULL);
7194   after_press (ctree, NULL);
7195 }
7196
7197 void change_style (GtkWidget *widget, GtkCTree *ctree)
7198 {
7199   static GtkStyle *style1 = NULL;
7200   static GtkStyle *style2 = NULL;
7201
7202   GtkCTreeNode *node;
7203   GdkColor col1;
7204   GdkColor col2;
7205
7206   if (GTK_CLIST (ctree)->focus_row >= 0)
7207     node = GTK_CTREE_NODE
7208       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
7209   else
7210     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
7211
7212   if (!node)
7213     return;
7214
7215   if (!style1)
7216     {
7217       col1.red   = 0;
7218       col1.green = 56000;
7219       col1.blue  = 0;
7220       col2.red   = 32000;
7221       col2.green = 0;
7222       col2.blue  = 56000;
7223
7224       style1 = gtk_style_new ();
7225       style1->base[GTK_STATE_NORMAL] = col1;
7226       style1->fg[GTK_STATE_SELECTED] = col2;
7227
7228       style2 = gtk_style_new ();
7229       style2->base[GTK_STATE_SELECTED] = col2;
7230       style2->fg[GTK_STATE_NORMAL] = col1;
7231       style2->base[GTK_STATE_NORMAL] = col2;
7232       pango_font_description_free (style2->font_desc);
7233       style2->font_desc = pango_font_description_from_string ("courier 30");
7234     }
7235
7236   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
7237   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
7238
7239   if (GTK_CTREE_ROW (node)->children)
7240     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
7241                                   style2);
7242 }
7243
7244 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
7245 {
7246   gtk_ctree_unselect_recursive (ctree, NULL);
7247   after_press (ctree, NULL);
7248 }
7249
7250 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
7251 {
7252   GtkCList *clist;
7253   GtkCTreeNode *node;
7254
7255   clist = GTK_CLIST (ctree);
7256
7257   gtk_clist_freeze (clist);
7258
7259   while (clist->selection)
7260     {
7261       node = clist->selection->data;
7262
7263       if (GTK_CTREE_ROW (node)->is_leaf)
7264         pages--;
7265       else
7266         gtk_ctree_post_recursive (ctree, node,
7267                                   (GtkCTreeFunc) count_items, NULL);
7268
7269       gtk_ctree_remove_node (ctree, node);
7270
7271       if (clist->selection_mode == GTK_SELECTION_BROWSE)
7272         break;
7273     }
7274
7275   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
7276       clist->focus_row >= 0)
7277     {
7278       node = gtk_ctree_node_nth (ctree, clist->focus_row);
7279
7280       if (node)
7281         gtk_ctree_select (ctree, node);
7282     }
7283     
7284   gtk_clist_thaw (clist);
7285   after_press (ctree, NULL);
7286 }
7287
7288 struct _ExportStruct {
7289   gchar *tree;
7290   gchar *info;
7291   gboolean is_leaf;
7292 };
7293
7294 typedef struct _ExportStruct ExportStruct;
7295
7296 gboolean
7297 gnode2ctree (GtkCTree   *ctree,
7298              guint       depth,
7299              GNode        *gnode,
7300              GtkCTreeNode *cnode,
7301              gpointer    data)
7302 {
7303   ExportStruct *es;
7304   GdkPixmap *pixmap_closed;
7305   GdkBitmap *mask_closed;
7306   GdkPixmap *pixmap_opened;
7307   GdkBitmap *mask_opened;
7308   CTreePixmaps *pixmaps;
7309
7310   if (!cnode || !gnode || (!(es = gnode->data)))
7311     return FALSE;
7312
7313   pixmaps = get_ctree_pixmaps (ctree);
7314
7315   if (es->is_leaf)
7316     {
7317       pixmap_closed = pixmaps->pixmap3;
7318       mask_closed = pixmaps->mask3;
7319       pixmap_opened = NULL;
7320       mask_opened = NULL;
7321     }
7322   else
7323     {
7324       pixmap_closed = pixmaps->pixmap1;
7325       mask_closed = pixmaps->mask1;
7326       pixmap_opened = pixmaps->pixmap2;
7327       mask_opened = pixmaps->mask2;
7328     }
7329
7330   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
7331                            mask_closed, pixmap_opened, mask_opened,
7332                            es->is_leaf, (depth < 3));
7333   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
7334   g_free (es);
7335   gnode->data = NULL;
7336
7337   return TRUE;
7338 }
7339
7340 gboolean
7341 ctree2gnode (GtkCTree   *ctree,
7342              guint       depth,
7343              GNode        *gnode,
7344              GtkCTreeNode *cnode,
7345              gpointer    data)
7346 {
7347   ExportStruct *es;
7348
7349   if (!cnode || !gnode)
7350     return FALSE;
7351   
7352   es = g_new (ExportStruct, 1);
7353   gnode->data = es;
7354   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
7355   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
7356   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
7357   return TRUE;
7358 }
7359
7360 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
7361 {
7362   char *title[] = { "Tree" , "Info" };
7363   static GtkWidget *export_window = NULL;
7364   static GtkCTree *export_ctree;
7365   GtkWidget *vbox;
7366   GtkWidget *scrolled_win;
7367   GtkWidget *button;
7368   GtkWidget *sep;
7369   GNode *gnode;
7370   GtkCTreeNode *node;
7371
7372   if (!export_window)
7373     {
7374       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7375
7376       gtk_window_set_screen (GTK_WINDOW (export_window),
7377                              gtk_widget_get_screen (widget));
7378   
7379       g_signal_connect (export_window, "destroy",
7380                         G_CALLBACK (gtk_widget_destroyed),
7381                         &export_window);
7382
7383       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
7384       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
7385
7386       vbox = gtk_vbox_new (FALSE, 0);
7387       gtk_container_add (GTK_CONTAINER (export_window), vbox);
7388       
7389       button = gtk_button_new_with_label ("Close");
7390       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
7391
7392       g_signal_connect_swapped (button, "clicked",
7393                                 G_CALLBACK (gtk_widget_destroy),
7394                                 export_window);
7395
7396       sep = gtk_hseparator_new ();
7397       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
7398
7399       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
7400       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
7401
7402       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
7403       gtk_container_add (GTK_CONTAINER (scrolled_win),
7404                          GTK_WIDGET (export_ctree));
7405       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
7406                                       GTK_POLICY_AUTOMATIC,
7407                                       GTK_POLICY_AUTOMATIC);
7408       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
7409       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
7410                                     GTK_SELECTION_EXTENDED);
7411       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
7412       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
7413       gtk_widget_set_size_request (GTK_WIDGET (export_ctree), 300, 200);
7414     }
7415
7416   if (!GTK_WIDGET_VISIBLE (export_window))
7417     gtk_widget_show_all (export_window);
7418       
7419   gtk_clist_clear (GTK_CLIST (export_ctree));
7420
7421   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
7422                                      GTK_CLIST (ctree)->focus_row));
7423   if (!node)
7424     return;
7425
7426   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
7427                                      ctree2gnode, NULL);
7428   if (gnode)
7429     {
7430       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
7431                               gnode2ctree, NULL);
7432       g_node_destroy (gnode);
7433     }
7434 }
7435
7436 void change_indent (GtkWidget *widget, GtkCTree *ctree)
7437 {
7438   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
7439 }
7440
7441 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
7442 {
7443   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
7444 }
7445
7446 void change_row_height (GtkWidget *widget, GtkCList *clist)
7447 {
7448   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
7449 }
7450
7451 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
7452 {
7453   GtkStyle *style = NULL;
7454   
7455   if (!node)
7456     return;
7457   
7458   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
7459     {
7460       if (!GTK_CTREE_ROW (node)->is_leaf)
7461         style = GTK_CTREE_ROW (node)->row.data;
7462       else if (GTK_CTREE_ROW (node)->parent)
7463         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
7464     }
7465
7466   gtk_ctree_node_set_row_style (ctree, node, style);
7467 }
7468
7469 void 
7470 ctree_toggle_line_style (GtkWidget *widget, gpointer data)
7471 {
7472   GtkCTree *ctree;
7473   gint i;
7474
7475   ctree = GTK_CTREE (data);
7476
7477   if (!GTK_WIDGET_MAPPED (widget))
7478     return;
7479
7480   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
7481
7482   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
7483        ((GtkCTreeLineStyle) i) != GTK_CTREE_LINES_TABBED) ||
7484       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
7485        ((GtkCTreeLineStyle) i) == GTK_CTREE_LINES_TABBED))
7486     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
7487   gtk_ctree_set_line_style (ctree, i);
7488   line_style = i;
7489 }
7490
7491 void 
7492 ctree_toggle_expander_style (GtkWidget *widget, gpointer data)
7493 {
7494   GtkCTree *ctree;
7495   gint i;
7496
7497   ctree = GTK_CTREE (data);
7498
7499   if (!GTK_WIDGET_MAPPED (widget))
7500     return;
7501   
7502   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
7503   
7504   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) i);
7505 }
7506
7507 void 
7508 ctree_toggle_justify (GtkWidget *widget, gpointer data)
7509 {
7510   GtkCTree *ctree;
7511   gint i;
7512
7513   ctree = GTK_CTREE (data);
7514
7515   if (!GTK_WIDGET_MAPPED (widget))
7516     return;
7517
7518   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
7519
7520   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
7521                                       (GtkJustification) i);
7522 }
7523
7524 void 
7525 ctree_toggle_sel_mode (GtkWidget *widget, gpointer data)
7526 {
7527   GtkCTree *ctree;
7528   gint i;
7529
7530   ctree = GTK_CTREE (data);
7531
7532   if (!GTK_WIDGET_MAPPED (widget))
7533     return;
7534
7535   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
7536
7537   gtk_clist_set_selection_mode (GTK_CLIST (ctree), selection_modes[i]);
7538   after_press (ctree, NULL);
7539 }
7540     
7541 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
7542                       gint num_books, gint num_pages, GtkCTreeNode *parent)
7543 {
7544   gchar *text[2];
7545   gchar buf1[60];
7546   gchar buf2[60];
7547   GtkCTreeNode *sibling;
7548   CTreePixmaps *pixmaps;
7549   gint i;
7550
7551   text[0] = buf1;
7552   text[1] = buf2;
7553   sibling = NULL;
7554
7555   pixmaps = get_ctree_pixmaps (ctree);
7556
7557   for (i = num_pages + num_books; i > num_books; i--)
7558     {
7559       pages++;
7560       sprintf (buf1, "Page %02d", (gint) rand() % 100);
7561       sprintf (buf2, "Item %d-%d", cur_depth, i);
7562       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
7563                                        pixmaps->pixmap3, pixmaps->mask3, NULL, NULL,
7564                                        TRUE, FALSE);
7565
7566       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
7567         gtk_ctree_node_set_row_style (ctree, sibling,
7568                                       GTK_CTREE_ROW (parent)->row.style);
7569     }
7570
7571   if (cur_depth == depth)
7572     return;
7573
7574   for (i = num_books; i > 0; i--)
7575     {
7576       GtkStyle *style;
7577
7578       books++;
7579       sprintf (buf1, "Book %02d", (gint) rand() % 100);
7580       sprintf (buf2, "Item %d-%d", cur_depth, i);
7581       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
7582                                        pixmaps->pixmap1, pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2,
7583                                        FALSE, FALSE);
7584
7585       style = gtk_style_new ();
7586       switch (cur_depth % 3)
7587         {
7588         case 0:
7589           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
7590           style->base[GTK_STATE_NORMAL].green = 0;
7591           style->base[GTK_STATE_NORMAL].blue  = 65535 - ((i * 10000) % 65535);
7592           break;
7593         case 1:
7594           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
7595           style->base[GTK_STATE_NORMAL].green = 65535 - ((i * 10000) % 65535);
7596           style->base[GTK_STATE_NORMAL].blue  = 0;
7597           break;
7598         default:
7599           style->base[GTK_STATE_NORMAL].red   = 65535 - ((i * 10000) % 65535);
7600           style->base[GTK_STATE_NORMAL].green = 0;
7601           style->base[GTK_STATE_NORMAL].blue  = 10000 * (cur_depth % 6);
7602           break;
7603         }
7604       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
7605                                         (GtkDestroyNotify) gtk_style_unref);
7606
7607       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
7608         gtk_ctree_node_set_row_style (ctree, sibling, style);
7609
7610       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
7611                        sibling);
7612     }
7613 }
7614
7615 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
7616 {
7617   gchar *text [2];
7618   gchar label1[] = "Root";
7619   gchar label2[] = "";
7620   GtkCTreeNode *parent;
7621   GtkStyle *style;
7622   guint b, d, p, n;
7623   CTreePixmaps *pixmaps;
7624
7625   pixmaps = get_ctree_pixmaps (ctree);
7626
7627   text[0] = label1;
7628   text[1] = label2;
7629   
7630   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
7631   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7632   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
7633
7634   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
7635
7636   if (n > 100000)
7637     {
7638       g_print ("%d total items? Try less\n",n);
7639       return;
7640     }
7641
7642   gtk_clist_freeze (GTK_CLIST (ctree));
7643   gtk_clist_clear (GTK_CLIST (ctree));
7644
7645   books = 1;
7646   pages = 0;
7647
7648   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmaps->pixmap1,
7649                                   pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2, FALSE, TRUE);
7650
7651   style = gtk_style_new ();
7652   style->base[GTK_STATE_NORMAL].red   = 0;
7653   style->base[GTK_STATE_NORMAL].green = 45000;
7654   style->base[GTK_STATE_NORMAL].blue  = 55000;
7655   gtk_ctree_node_set_row_data_full (ctree, parent, style,
7656                                     (GtkDestroyNotify) gtk_style_unref);
7657
7658   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
7659     gtk_ctree_node_set_row_style (ctree, parent, style);
7660
7661   build_recursive (ctree, 1, d, b, p, parent);
7662   gtk_clist_thaw (GTK_CLIST (ctree));
7663   after_press (ctree, NULL);
7664 }
7665
7666 static void 
7667 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
7668 {
7669   GtkCList *clist;
7670
7671   clist = GTK_CLIST (ctree);
7672
7673   if (column == clist->sort_column)
7674     {
7675       if (clist->sort_type == GTK_SORT_ASCENDING)
7676         clist->sort_type = GTK_SORT_DESCENDING;
7677       else
7678         clist->sort_type = GTK_SORT_ASCENDING;
7679     }
7680   else
7681     gtk_clist_set_sort_column (clist, column);
7682
7683   gtk_ctree_sort_recursive (ctree, NULL);
7684 }
7685
7686 void create_ctree (GtkWidget *widget)
7687 {
7688   static GtkWidget *window = NULL;
7689   GtkTooltips *tooltips;
7690   GtkCTree *ctree;
7691   GtkWidget *scrolled_win;
7692   GtkWidget *vbox;
7693   GtkWidget *bbox;
7694   GtkWidget *mbox;
7695   GtkWidget *hbox;
7696   GtkWidget *hbox2;
7697   GtkWidget *frame;
7698   GtkWidget *label;
7699   GtkWidget *button;
7700   GtkWidget *check;
7701   GtkAdjustment *adj;
7702   GtkWidget *spinner;
7703
7704   char *title[] = { "Tree" , "Info" };
7705   char buf[80];
7706
7707   static gchar *items1[] =
7708   {
7709     "No lines",
7710     "Solid",
7711     "Dotted",
7712     "Tabbed"
7713   };
7714
7715   static gchar *items2[] =
7716   {
7717     "None",
7718     "Square",
7719     "Triangle",
7720     "Circular"
7721   };
7722
7723   static gchar *items3[] =
7724   {
7725     "Left",
7726     "Right"
7727   };
7728   
7729   if (!window)
7730     {
7731       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7732       gtk_window_set_screen (GTK_WINDOW (window), 
7733                              gtk_widget_get_screen (widget));
7734
7735       g_signal_connect (window, "destroy",
7736                         G_CALLBACK (gtk_widget_destroyed),
7737                         &window);
7738
7739       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
7740       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7741
7742       tooltips = gtk_tooltips_new ();
7743       g_object_ref (tooltips);
7744       gtk_object_sink (GTK_OBJECT (tooltips));
7745
7746       g_object_set_data_full (G_OBJECT (window), "tooltips", tooltips,
7747                               g_object_unref);
7748
7749       vbox = gtk_vbox_new (FALSE, 0);
7750       gtk_container_add (GTK_CONTAINER (window), vbox);
7751
7752       hbox = gtk_hbox_new (FALSE, 5);
7753       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
7754       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
7755       
7756       label = gtk_label_new ("Depth :");
7757       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7758       
7759       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
7760       spin1 = gtk_spin_button_new (adj, 0, 0);
7761       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
7762   
7763       label = gtk_label_new ("Books :");
7764       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7765       
7766       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
7767       spin2 = gtk_spin_button_new (adj, 0, 0);
7768       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
7769
7770       label = gtk_label_new ("Pages :");
7771       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7772       
7773       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
7774       spin3 = gtk_spin_button_new (adj, 0, 0);
7775       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
7776
7777       button = gtk_button_new_with_label ("Close");
7778       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7779
7780       g_signal_connect_swapped (button, "clicked",
7781                                 G_CALLBACK (gtk_widget_destroy),
7782                                 window);
7783
7784       button = gtk_button_new_with_label ("Rebuild Tree");
7785       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7786
7787       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
7788       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
7789       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
7790                                       GTK_POLICY_AUTOMATIC,
7791                                       GTK_POLICY_ALWAYS);
7792       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
7793
7794       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
7795       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
7796
7797       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
7798       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
7799       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
7800       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
7801       line_style = GTK_CTREE_LINES_DOTTED;
7802
7803       g_signal_connect (button, "clicked",
7804                         G_CALLBACK (rebuild_tree), ctree);
7805       g_signal_connect (ctree, "click_column",
7806                         G_CALLBACK (ctree_click_column), NULL);
7807
7808       g_signal_connect_after (ctree, "button_press_event",
7809                               G_CALLBACK (after_press), NULL);
7810       g_signal_connect_after (ctree, "button_release_event",
7811                               G_CALLBACK (after_press), NULL);
7812       g_signal_connect_after (ctree, "tree_move",
7813                               G_CALLBACK (after_move), NULL);
7814       g_signal_connect_after (ctree, "end_selection",
7815                               G_CALLBACK (after_press), NULL);
7816       g_signal_connect_after (ctree, "toggle_focus_row",
7817                               G_CALLBACK (after_press), NULL);
7818       g_signal_connect_after (ctree, "select_all",
7819                               G_CALLBACK (after_press), NULL);
7820       g_signal_connect_after (ctree, "unselect_all",
7821                               G_CALLBACK (after_press), NULL);
7822       g_signal_connect_after (ctree, "scroll_vertical",
7823                               G_CALLBACK (after_press), NULL);
7824
7825       bbox = gtk_hbox_new (FALSE, 5);
7826       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
7827       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
7828
7829       mbox = gtk_vbox_new (TRUE, 5);
7830       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
7831
7832       label = gtk_label_new ("Row Height :");
7833       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
7834
7835       label = gtk_label_new ("Indent :");
7836       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
7837
7838       label = gtk_label_new ("Spacing :");
7839       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
7840
7841       mbox = gtk_vbox_new (TRUE, 5);
7842       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
7843
7844       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
7845       spinner = gtk_spin_button_new (adj, 0, 0);
7846       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
7847       gtk_tooltips_set_tip (tooltips, spinner,
7848                             "Row height of list items", NULL);
7849       g_signal_connect (adj, "value_changed",
7850                         G_CALLBACK (change_row_height), ctree);
7851       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
7852
7853       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
7854       spinner = gtk_spin_button_new (adj, 0, 0);
7855       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
7856       gtk_tooltips_set_tip (tooltips, spinner, "Tree Indentation.", NULL);
7857       g_signal_connect (adj, "value_changed",
7858                         G_CALLBACK (change_indent), ctree);
7859
7860       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
7861       spinner = gtk_spin_button_new (adj, 0, 0);
7862       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
7863       gtk_tooltips_set_tip (tooltips, spinner, "Tree Spacing.", NULL);
7864       g_signal_connect (adj, "value_changed",
7865                         G_CALLBACK (change_spacing), ctree);
7866
7867       mbox = gtk_vbox_new (TRUE, 5);
7868       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
7869
7870       hbox = gtk_hbox_new (FALSE, 5);
7871       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
7872
7873       button = gtk_button_new_with_label ("Expand All");
7874       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7875       g_signal_connect (button, "clicked",
7876                         G_CALLBACK (expand_all), ctree);
7877
7878       button = gtk_button_new_with_label ("Collapse All");
7879       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7880       g_signal_connect (button, "clicked",
7881                         G_CALLBACK (collapse_all), ctree);
7882
7883       button = gtk_button_new_with_label ("Change Style");
7884       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7885       g_signal_connect (button, "clicked",
7886                         G_CALLBACK (change_style), ctree);
7887
7888       button = gtk_button_new_with_label ("Export Tree");
7889       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7890       g_signal_connect (button, "clicked",
7891                         G_CALLBACK (export_ctree), ctree);
7892
7893       hbox = gtk_hbox_new (FALSE, 5);
7894       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
7895
7896       button = gtk_button_new_with_label ("Select All");
7897       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7898       g_signal_connect (button, "clicked",
7899                         G_CALLBACK (select_all), ctree);
7900
7901       button = gtk_button_new_with_label ("Unselect All");
7902       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7903       g_signal_connect (button, "clicked",
7904                         G_CALLBACK (unselect_all), ctree);
7905
7906       button = gtk_button_new_with_label ("Remove Selection");
7907       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
7908       g_signal_connect (button, "clicked",
7909                         G_CALLBACK (remove_selection), ctree);
7910
7911       check = gtk_check_button_new_with_label ("Reorderable");
7912       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
7913       gtk_tooltips_set_tip (tooltips, check,
7914                             "Tree items can be reordered by dragging.", NULL);
7915       g_signal_connect (check, "clicked",
7916                         G_CALLBACK (toggle_reorderable), ctree);
7917       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
7918
7919       hbox = gtk_hbox_new (TRUE, 5);
7920       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
7921
7922       omenu1 = build_option_menu (items1, 4, 2, 
7923                                   ctree_toggle_line_style,
7924                                   ctree);
7925       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
7926       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
7927
7928       omenu2 = build_option_menu (items2, 4, 1, 
7929                                   ctree_toggle_expander_style,
7930                                   ctree);
7931       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
7932       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
7933                             NULL);
7934
7935       omenu3 = build_option_menu (items3, 2, 0, 
7936                                   ctree_toggle_justify, ctree);
7937       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
7938       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
7939                             NULL);
7940
7941       omenu4 = build_option_menu (selection_mode_items, 3, 3, 
7942                                   ctree_toggle_sel_mode, ctree);
7943       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
7944       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
7945                             NULL);
7946
7947       gtk_widget_realize (window);
7948       
7949       gtk_widget_set_size_request (GTK_WIDGET (ctree), -1, 300);
7950
7951       frame = gtk_frame_new (NULL);
7952       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
7953       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
7954       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
7955
7956       hbox = gtk_hbox_new (TRUE, 2);
7957       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
7958       gtk_container_add (GTK_CONTAINER (frame), hbox);
7959
7960       frame = gtk_frame_new (NULL);
7961       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
7962       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
7963
7964       hbox2 = gtk_hbox_new (FALSE, 0);
7965       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
7966       gtk_container_add (GTK_CONTAINER (frame), hbox2);
7967
7968       label = gtk_label_new ("Books :");
7969       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
7970
7971       sprintf (buf, "%d", books);
7972       book_label = gtk_label_new (buf);
7973       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
7974
7975       frame = gtk_frame_new (NULL);
7976       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
7977       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
7978
7979       hbox2 = gtk_hbox_new (FALSE, 0);
7980       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
7981       gtk_container_add (GTK_CONTAINER (frame), hbox2);
7982
7983       label = gtk_label_new ("Pages :");
7984       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
7985
7986       sprintf (buf, "%d", pages);
7987       page_label = gtk_label_new (buf);
7988       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
7989
7990       frame = gtk_frame_new (NULL);
7991       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
7992       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
7993
7994       hbox2 = gtk_hbox_new (FALSE, 0);
7995       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
7996       gtk_container_add (GTK_CONTAINER (frame), hbox2);
7997
7998       label = gtk_label_new ("Selected :");
7999       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
8000
8001       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
8002       sel_label = gtk_label_new (buf);
8003       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
8004
8005       frame = gtk_frame_new (NULL);
8006       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
8007       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
8008
8009       hbox2 = gtk_hbox_new (FALSE, 0);
8010       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
8011       gtk_container_add (GTK_CONTAINER (frame), hbox2);
8012
8013       label = gtk_label_new ("Visible :");
8014       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
8015
8016       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
8017       vis_label = gtk_label_new (buf);
8018       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
8019
8020       rebuild_tree (NULL, ctree);
8021     }
8022
8023   if (!GTK_WIDGET_VISIBLE (window))
8024     gtk_widget_show_all (window);
8025   else
8026     gtk_widget_destroy (window);
8027 }
8028
8029 /*
8030  * GtkColorSelection
8031  */
8032
8033 void
8034 color_selection_ok (GtkWidget               *w,
8035                     GtkColorSelectionDialog *cs)
8036 {
8037   GtkColorSelection *colorsel;
8038   gdouble color[4];
8039
8040   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
8041
8042   gtk_color_selection_get_color(colorsel,color);
8043   gtk_color_selection_set_color(colorsel,color);
8044 }
8045
8046 void
8047 color_selection_changed (GtkWidget *w,
8048                          GtkColorSelectionDialog *cs)
8049 {
8050   GtkColorSelection *colorsel;
8051   gdouble color[4];
8052
8053   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
8054   gtk_color_selection_get_color(colorsel,color);
8055 }
8056
8057 #if 0 /* unused */
8058 static void
8059 opacity_toggled_cb (GtkWidget *w,
8060                     GtkColorSelectionDialog *cs)
8061 {
8062   GtkColorSelection *colorsel;
8063
8064   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
8065   gtk_color_selection_set_has_opacity_control (colorsel,
8066                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
8067 }
8068
8069 static void
8070 palette_toggled_cb (GtkWidget *w,
8071                     GtkColorSelectionDialog *cs)
8072 {
8073   GtkColorSelection *colorsel;
8074
8075   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
8076   gtk_color_selection_set_has_palette (colorsel,
8077                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
8078 }
8079 #endif
8080
8081 void
8082 create_color_selection (GtkWidget *widget)
8083 {
8084   static GtkWidget *window = NULL;
8085
8086   if (!window)
8087     {
8088       GtkWidget *picker;
8089       GtkWidget *hbox;
8090       GtkWidget *label;
8091       
8092       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8093       gtk_window_set_screen (GTK_WINDOW (window), 
8094                              gtk_widget_get_screen (widget));
8095                              
8096       g_signal_connect (window, "destroy",
8097                         G_CALLBACK (gtk_widget_destroyed),
8098                         &window);
8099
8100       gtk_window_set_title (GTK_WINDOW (window), "GtkColorButton");
8101       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8102
8103       hbox = gtk_hbox_new (FALSE, 8);
8104       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
8105       gtk_container_add (GTK_CONTAINER (window), hbox);
8106       
8107       label = gtk_label_new ("Pick a color");
8108       gtk_container_add (GTK_CONTAINER (hbox), label);
8109
8110       picker = gtk_color_button_new ();
8111       gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (picker), TRUE);
8112       gtk_container_add (GTK_CONTAINER (hbox), picker);
8113     }
8114
8115   if (!GTK_WIDGET_VISIBLE (window))
8116     gtk_widget_show_all (window);
8117   else
8118     gtk_widget_destroy (window);
8119 }
8120
8121 /*
8122  * GtkFileSelection
8123  */
8124
8125 void
8126 show_fileops (GtkWidget        *widget,
8127               GtkFileSelection *fs)
8128 {
8129   gboolean show_ops;
8130
8131   show_ops = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8132
8133   if (show_ops)
8134     gtk_file_selection_show_fileop_buttons (fs);
8135   else
8136     gtk_file_selection_hide_fileop_buttons (fs);
8137 }
8138
8139 void
8140 select_multiple (GtkWidget        *widget,
8141                  GtkFileSelection *fs)
8142 {
8143   gboolean select_multiple;
8144
8145   select_multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8146   gtk_file_selection_set_select_multiple (fs, select_multiple);
8147 }
8148
8149 void
8150 file_selection_ok (GtkFileSelection *fs)
8151 {
8152   int i;
8153   gchar **selections;
8154
8155   selections = gtk_file_selection_get_selections (fs);
8156
8157   for (i = 0; selections[i] != NULL; i++)
8158     g_print ("%s\n", selections[i]);
8159
8160   g_strfreev (selections);
8161
8162   gtk_widget_destroy (GTK_WIDGET (fs));
8163 }
8164
8165 void
8166 create_file_selection (GtkWidget *widget)
8167 {
8168   static GtkWidget *window = NULL;
8169   GtkWidget *button;
8170
8171   if (!window)
8172     {
8173       window = gtk_file_selection_new ("file selection dialog");
8174       gtk_window_set_screen (GTK_WINDOW (window),
8175                              gtk_widget_get_screen (widget));
8176
8177       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
8178
8179       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
8180
8181       g_signal_connect (window, "destroy",
8182                         G_CALLBACK (gtk_widget_destroyed),
8183                         &window);
8184
8185       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button,
8186                                 "clicked",
8187                                 G_CALLBACK (file_selection_ok),
8188                                 window);
8189       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button,
8190                                 "clicked",
8191                                 G_CALLBACK (gtk_widget_destroy),
8192                                 window);
8193       
8194       button = gtk_check_button_new_with_label ("Show Fileops");
8195       g_signal_connect (button, "toggled",
8196                         G_CALLBACK (show_fileops),
8197                         window);
8198       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
8199                           button, FALSE, FALSE, 0);
8200       gtk_widget_show (button);
8201
8202       button = gtk_check_button_new_with_label ("Select Multiple");
8203       g_signal_connect (button, "clicked",
8204                         G_CALLBACK (select_multiple),
8205                         window);
8206       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
8207                           button, FALSE, FALSE, 0);
8208       gtk_widget_show (button);
8209     }
8210   
8211   if (!GTK_WIDGET_VISIBLE (window))
8212     gtk_widget_show (window);
8213   else
8214     gtk_widget_destroy (window);
8215 }
8216
8217 void
8218 flipping_toggled_cb (GtkWidget *widget, gpointer data)
8219 {
8220   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8221   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
8222
8223   gtk_widget_set_default_direction (new_direction);
8224 }
8225
8226 static void
8227 set_direction_recurse (GtkWidget *widget,
8228                        gpointer   data)
8229 {
8230   GtkTextDirection *dir = data;
8231   
8232   gtk_widget_set_direction (widget, *dir);
8233   if (GTK_IS_CONTAINER (widget))
8234     gtk_container_foreach (GTK_CONTAINER (widget),
8235                            set_direction_recurse,
8236                            data);
8237 }
8238
8239 static GtkWidget *
8240 create_forward_back (const char       *title,
8241                      GtkTextDirection  text_dir)
8242 {
8243   GtkWidget *frame = gtk_frame_new (title);
8244   GtkWidget *bbox = gtk_hbutton_box_new ();
8245   GtkWidget *back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
8246   GtkWidget *forward_button = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
8247
8248   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
8249   
8250   gtk_container_add (GTK_CONTAINER (frame), bbox);
8251   gtk_container_add (GTK_CONTAINER (bbox), back_button);
8252   gtk_container_add (GTK_CONTAINER (bbox), forward_button);
8253
8254   set_direction_recurse (frame, &text_dir);
8255
8256   return frame;
8257 }
8258
8259 void
8260 create_flipping (GtkWidget *widget)
8261 {
8262   static GtkWidget *window = NULL;
8263   GtkWidget *check_button, *button;
8264
8265   if (!window)
8266     {
8267       window = gtk_dialog_new ();
8268
8269       gtk_window_set_screen (GTK_WINDOW (window),
8270                              gtk_widget_get_screen (widget));
8271
8272       g_signal_connect (window, "destroy",
8273                         G_CALLBACK (gtk_widget_destroyed),
8274                         &window);
8275
8276       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
8277
8278       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
8279       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8280                           check_button, TRUE, TRUE, 0);
8281
8282       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8283                           create_forward_back ("Default", GTK_TEXT_DIR_NONE),
8284                           TRUE, TRUE, 0);
8285
8286       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8287                           create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
8288                           TRUE, TRUE, 0);
8289
8290       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8291                           create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
8292                           TRUE, TRUE, 0);
8293
8294       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
8295         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
8296
8297       g_signal_connect (check_button, "toggled",
8298                         G_CALLBACK (flipping_toggled_cb), NULL);
8299
8300       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
8301       
8302       button = gtk_button_new_with_label ("Close");
8303       g_signal_connect_swapped (button, "clicked",
8304                                 G_CALLBACK (gtk_widget_destroy), window);
8305       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8306                           button, TRUE, TRUE, 0);
8307     }
8308   
8309   if (!GTK_WIDGET_VISIBLE (window))
8310     gtk_widget_show_all (window);
8311   else
8312     gtk_widget_destroy (window);
8313 }
8314
8315 /*
8316  * Focus test
8317  */
8318
8319 static GtkWidget*
8320 make_focus_table (GList **list)
8321 {
8322   GtkWidget *table;
8323   gint i, j;
8324   
8325   table = gtk_table_new (5, 5, FALSE);
8326
8327   i = 0;
8328   j = 0;
8329
8330   while (i < 5)
8331     {
8332       j = 0;
8333       while (j < 5)
8334         {
8335           GtkWidget *widget;
8336           
8337           if ((i + j) % 2)
8338             widget = gtk_entry_new ();
8339           else
8340             widget = gtk_button_new_with_label ("Foo");
8341
8342           *list = g_list_prepend (*list, widget);
8343           
8344           gtk_table_attach (GTK_TABLE (table),
8345                             widget,
8346                             i, i + 1,
8347                             j, j + 1,
8348                             GTK_EXPAND | GTK_FILL,
8349                             GTK_EXPAND | GTK_FILL,
8350                             5, 5);
8351           
8352           ++j;
8353         }
8354
8355       ++i;
8356     }
8357
8358   *list = g_list_reverse (*list);
8359   
8360   return table;
8361 }
8362
8363 static void
8364 create_focus (GtkWidget *widget)
8365 {
8366   static GtkWidget *window = NULL;
8367   
8368   if (!window)
8369     {
8370       GtkWidget *table;
8371       GtkWidget *frame;
8372       GList *list = NULL;
8373       
8374       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
8375                                             NULL, 0,
8376                                             GTK_STOCK_CLOSE,
8377                                             GTK_RESPONSE_NONE,
8378                                             NULL);
8379
8380       gtk_window_set_screen (GTK_WINDOW (window),
8381                              gtk_widget_get_screen (widget));
8382
8383       g_signal_connect (window, "destroy",
8384                         G_CALLBACK (gtk_widget_destroyed),
8385                         &window);
8386
8387       g_signal_connect (window, "response",
8388                         G_CALLBACK (gtk_widget_destroy),
8389                         NULL);
8390       
8391       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
8392
8393       frame = gtk_frame_new ("Weird tab focus chain");
8394
8395       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8396                           frame, TRUE, TRUE, 0);
8397       
8398       table = make_focus_table (&list);
8399
8400       gtk_container_add (GTK_CONTAINER (frame), table);
8401
8402       gtk_container_set_focus_chain (GTK_CONTAINER (table),
8403                                      list);
8404
8405       g_list_free (list);
8406       
8407       frame = gtk_frame_new ("Default tab focus chain");
8408
8409       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8410                           frame, TRUE, TRUE, 0);
8411
8412       list = NULL;
8413       table = make_focus_table (&list);
8414
8415       g_list_free (list);
8416       
8417       gtk_container_add (GTK_CONTAINER (frame), table);      
8418     }
8419   
8420   if (!GTK_WIDGET_VISIBLE (window))
8421     gtk_widget_show_all (window);
8422   else
8423     gtk_widget_destroy (window);
8424 }
8425
8426 /*
8427  * GtkFontSelection
8428  */
8429
8430 void
8431 font_selection_ok (GtkWidget              *w,
8432                    GtkFontSelectionDialog *fs)
8433 {
8434   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
8435
8436   g_print ("%s\n", s);
8437   g_free (s);
8438   gtk_widget_destroy (GTK_WIDGET (fs));
8439 }
8440
8441 void
8442 create_font_selection (GtkWidget *widget)
8443 {
8444   static GtkWidget *window = NULL;
8445
8446   if (!window)
8447     {
8448       GtkWidget *picker;
8449       GtkWidget *hbox;
8450       GtkWidget *label;
8451       
8452       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8453       gtk_window_set_screen (GTK_WINDOW (window),
8454                              gtk_widget_get_screen (widget));
8455
8456       g_signal_connect (window, "destroy",
8457                         G_CALLBACK (gtk_widget_destroyed),
8458                         &window);
8459
8460       gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
8461       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8462
8463       hbox = gtk_hbox_new (FALSE, 8);
8464       gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
8465       gtk_container_add (GTK_CONTAINER (window), hbox);
8466       
8467       label = gtk_label_new ("Pick a font");
8468       gtk_container_add (GTK_CONTAINER (hbox), label);
8469
8470       picker = gtk_font_button_new ();
8471       gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
8472       gtk_container_add (GTK_CONTAINER (hbox), picker);
8473     }
8474   
8475   if (!GTK_WIDGET_VISIBLE (window))
8476     gtk_widget_show_all (window);
8477   else
8478     gtk_widget_destroy (window);
8479 }
8480
8481 /*
8482  * GtkDialog
8483  */
8484
8485 static GtkWidget *dialog_window = NULL;
8486
8487 static void
8488 label_toggle (GtkWidget  *widget,
8489               GtkWidget **label)
8490 {
8491   if (!(*label))
8492     {
8493       *label = gtk_label_new ("Dialog Test");
8494       g_signal_connect (*label,
8495                         "destroy",
8496                         G_CALLBACK (gtk_widget_destroyed),
8497                         label);
8498       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
8499       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
8500                           *label, TRUE, TRUE, 0);
8501       gtk_widget_show (*label);
8502     }
8503   else
8504     gtk_widget_destroy (*label);
8505 }
8506
8507 #define RESPONSE_TOGGLE_SEPARATOR 1
8508
8509 static void
8510 print_response (GtkWidget *dialog,
8511                 gint       response_id,
8512                 gpointer   data)
8513 {
8514   g_print ("response signal received (%d)\n", response_id);
8515
8516   if (response_id == RESPONSE_TOGGLE_SEPARATOR)
8517     {
8518       gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
8519                                     !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
8520     }
8521 }
8522
8523 static void
8524 create_dialog (GtkWidget *widget)
8525 {
8526   static GtkWidget *label;
8527   GtkWidget *button;
8528
8529   if (!dialog_window)
8530     {
8531       /* This is a terrible example; it's much simpler to create
8532        * dialogs than this. Don't use testgtk for example code,
8533        * use gtk-demo ;-)
8534        */
8535       
8536       dialog_window = gtk_dialog_new ();
8537       gtk_window_set_screen (GTK_WINDOW (dialog_window),
8538                              gtk_widget_get_screen (widget));
8539
8540       g_signal_connect (dialog_window,
8541                         "response",
8542                         G_CALLBACK (print_response),
8543                         NULL);
8544       
8545       g_signal_connect (dialog_window, "destroy",
8546                         G_CALLBACK (gtk_widget_destroyed),
8547                         &dialog_window);
8548
8549       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
8550       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
8551
8552       button = gtk_button_new_with_label ("OK");
8553       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8554       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
8555                           button, TRUE, TRUE, 0);
8556       gtk_widget_grab_default (button);
8557       gtk_widget_show (button);
8558
8559       button = gtk_button_new_with_label ("Toggle");
8560       g_signal_connect (button, "clicked",
8561                         G_CALLBACK (label_toggle),
8562                         &label);
8563       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8564       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
8565                           button, TRUE, TRUE, 0);
8566       gtk_widget_show (button);
8567
8568       label = NULL;
8569       
8570       button = gtk_button_new_with_label ("Separator");
8571
8572       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8573
8574       gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
8575                                     button,
8576                                     RESPONSE_TOGGLE_SEPARATOR);
8577       gtk_widget_show (button);
8578     }
8579
8580   if (!GTK_WIDGET_VISIBLE (dialog_window))
8581     gtk_widget_show (dialog_window);
8582   else
8583     gtk_widget_destroy (dialog_window);
8584 }
8585
8586 /* Display & Screen test 
8587  */
8588
8589 typedef struct 
8590
8591   GtkEntry *entry;
8592   GtkWidget *radio_dpy;
8593   GtkWidget *toplevel; 
8594   GtkWidget *dialog_window;
8595   GList *valid_display_list;
8596 } ScreenDisplaySelection;
8597
8598 static gint
8599 display_name_cmp (gconstpointer a,
8600                   gconstpointer b)
8601 {
8602   return g_ascii_strcasecmp (a,b);
8603 }
8604
8605 static void
8606 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
8607 {
8608   char *display_name;
8609   GdkDisplay *display = gtk_widget_get_display (widget);
8610   GtkWidget *dialog;
8611   GdkScreen *new_screen = NULL;
8612   GdkScreen *current_screen = gtk_widget_get_screen (widget);
8613   
8614   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
8615     {
8616       display_name = g_strdup (gtk_entry_get_text (data->entry));
8617       display = gdk_display_open (display_name);
8618       
8619       if (!display)
8620         {
8621           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
8622                                            GTK_DIALOG_DESTROY_WITH_PARENT,
8623                                            GTK_MESSAGE_ERROR,
8624                                            GTK_BUTTONS_OK,
8625                                            "The display :\n%s\ncannot be opened",
8626                                            display_name);
8627           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
8628           gtk_widget_show (dialog);
8629           g_signal_connect (dialog, "response",
8630                             G_CALLBACK (gtk_widget_destroy),
8631                             NULL);
8632         }
8633       else
8634         {
8635           if (!g_list_find_custom (data->valid_display_list, 
8636                                    display_name,
8637                                    display_name_cmp))
8638             data->valid_display_list = g_list_append (data->valid_display_list,
8639                                                       display_name);
8640           
8641           new_screen = gdk_display_get_default_screen (display);
8642         }
8643     }
8644   else
8645     {
8646       gint number_of_screens = gdk_display_get_n_screens (display);
8647       gint screen_num = gdk_screen_get_number (current_screen);
8648       if ((screen_num +1) < number_of_screens)
8649         new_screen = gdk_display_get_screen (display, screen_num + 1);
8650       else
8651         new_screen = gdk_display_get_screen (display, 0);
8652     }
8653   
8654   if (new_screen) 
8655     {
8656       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
8657       gtk_widget_destroy (data->dialog_window);
8658     }
8659 }
8660
8661 void
8662 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
8663 {
8664   gtk_widget_destroy (data);
8665 }
8666
8667 void
8668 create_display_screen (GtkWidget *widget)
8669 {
8670   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
8671   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
8672   GtkWidget *bbox;
8673   ScreenDisplaySelection *scr_dpy_data;
8674   GdkScreen *screen = gtk_widget_get_screen (widget);
8675   static GList *valid_display_list = NULL;
8676   
8677   GdkDisplay *display = gdk_screen_get_display (screen);
8678
8679   window = gtk_widget_new (gtk_window_get_type (),
8680                            "screen", screen,
8681                            "user_data", NULL,
8682                            "type", GTK_WINDOW_TOPLEVEL,
8683                            "title",
8684                            "Screen or Display selection",
8685                            "border_width", 10, NULL);
8686   g_signal_connect (window, "destroy", 
8687                     G_CALLBACK (gtk_widget_destroy), NULL);
8688
8689   vbox = gtk_vbox_new (FALSE, 3);
8690   gtk_container_add (GTK_CONTAINER (window), vbox);
8691   
8692   frame = gtk_frame_new ("Select screen or display");
8693   gtk_container_add (GTK_CONTAINER (vbox), frame);
8694   
8695   table = gtk_table_new (2, 2, TRUE);
8696   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
8697   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
8698
8699   gtk_container_add (GTK_CONTAINER (frame), table);
8700
8701   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
8702   if (gdk_display_get_n_screens(display) > 1)
8703     radio_scr = gtk_radio_button_new_with_label 
8704     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
8705   else
8706     {    
8707       radio_scr = gtk_radio_button_new_with_label 
8708         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
8709          "only one screen on the current display");
8710       gtk_widget_set_sensitive (radio_scr, FALSE);
8711     }
8712   combo_dpy = gtk_combo_new ();
8713   if (!valid_display_list)
8714     valid_display_list = g_list_append (valid_display_list, "diabolo:0.0");
8715     
8716   gtk_combo_set_popdown_strings (GTK_COMBO (combo_dpy), valid_display_list);
8717     
8718   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_dpy)->entry), 
8719                       "<hostname>:<X Server Num>.<Screen Num>");
8720
8721   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
8722   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
8723   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
8724
8725   bbox = gtk_hbutton_box_new ();
8726   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
8727   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
8728   
8729   gtk_container_add (GTK_CONTAINER (vbox), bbox);
8730
8731   gtk_container_add (GTK_CONTAINER (bbox), applyb);
8732   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
8733
8734   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
8735
8736   scr_dpy_data->entry = GTK_ENTRY (GTK_COMBO (combo_dpy)->entry);
8737   scr_dpy_data->radio_dpy = radio_dpy;
8738   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
8739   scr_dpy_data->dialog_window = window;
8740   scr_dpy_data->valid_display_list = valid_display_list;
8741
8742   g_signal_connect (cancelb, "clicked", 
8743                     G_CALLBACK (screen_display_destroy_diag), window);
8744   g_signal_connect (applyb, "clicked", 
8745                     G_CALLBACK (screen_display_check), scr_dpy_data);
8746   gtk_widget_show_all (window);
8747 }
8748
8749 /* Event Watcher
8750  */
8751 static gboolean event_watcher_enter_id = 0;
8752 static gboolean event_watcher_leave_id = 0;
8753
8754 static gboolean
8755 event_watcher (GSignalInvocationHint *ihint,
8756                guint                  n_param_values,
8757                const GValue          *param_values,
8758                gpointer               data)
8759 {
8760   g_print ("Watch: \"%s\" emitted for %s\n",
8761            g_signal_name (ihint->signal_id),
8762            G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
8763
8764   return TRUE;
8765 }
8766
8767 static void
8768 event_watcher_down (void)
8769 {
8770   if (event_watcher_enter_id)
8771     {
8772       guint signal_id;
8773
8774       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
8775       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
8776       event_watcher_enter_id = 0;
8777       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
8778       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
8779       event_watcher_leave_id = 0;
8780     }
8781 }
8782
8783 static void
8784 event_watcher_toggle (void)
8785 {
8786   if (event_watcher_enter_id)
8787     event_watcher_down ();
8788   else
8789     {
8790       guint signal_id;
8791
8792       signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
8793       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
8794       signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
8795       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
8796     }
8797 }
8798
8799 static void
8800 create_event_watcher (GtkWidget *widget)
8801 {
8802   GtkWidget *button;
8803
8804   if (!dialog_window)
8805     {
8806       dialog_window = gtk_dialog_new ();
8807       gtk_window_set_screen (GTK_WINDOW (dialog_window),
8808                              gtk_widget_get_screen (widget));
8809
8810       g_signal_connect (dialog_window, "destroy",
8811                         G_CALLBACK (gtk_widget_destroyed),
8812                         &dialog_window);
8813       g_signal_connect (dialog_window, "destroy",
8814                         G_CALLBACK (event_watcher_down),
8815                         NULL);
8816
8817       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
8818       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
8819       gtk_widget_set_size_request (dialog_window, 200, 110);
8820
8821       button = gtk_toggle_button_new_with_label ("Activate Watch");
8822       g_signal_connect (button, "clicked",
8823                         G_CALLBACK (event_watcher_toggle),
8824                         NULL);
8825       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
8826       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
8827                           button, TRUE, TRUE, 0);
8828       gtk_widget_show (button);
8829
8830       button = gtk_button_new_with_label ("Close");
8831       g_signal_connect_swapped (button, "clicked",
8832                                 G_CALLBACK (gtk_widget_destroy),
8833                                 dialog_window);
8834       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8835       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
8836                           button, TRUE, TRUE, 0);
8837       gtk_widget_grab_default (button);
8838       gtk_widget_show (button);
8839     }
8840
8841   if (!GTK_WIDGET_VISIBLE (dialog_window))
8842     gtk_widget_show (dialog_window);
8843   else
8844     gtk_widget_destroy (dialog_window);
8845 }
8846
8847 /*
8848  * GtkRange
8849  */
8850
8851 static gchar*
8852 reformat_value (GtkScale *scale,
8853                 gdouble   value)
8854 {
8855   return g_strdup_printf ("-->%0.*g<--",
8856                           gtk_scale_get_digits (scale), value);
8857 }
8858
8859 static void
8860 create_range_controls (GtkWidget *widget)
8861 {
8862   static GtkWidget *window = NULL;
8863   GtkWidget *box1;
8864   GtkWidget *box2;
8865   GtkWidget *button;
8866   GtkWidget *scrollbar;
8867   GtkWidget *scale;
8868   GtkWidget *separator;
8869   GtkObject *adjustment;
8870   GtkWidget *hbox;
8871
8872   if (!window)
8873     {
8874       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8875
8876       gtk_window_set_screen (GTK_WINDOW (window),
8877                              gtk_widget_get_screen (widget));
8878
8879       g_signal_connect (window, "destroy",
8880                         G_CALLBACK (gtk_widget_destroyed),
8881                         &window);
8882
8883       gtk_window_set_title (GTK_WINDOW (window), "range controls");
8884       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8885
8886
8887       box1 = gtk_vbox_new (FALSE, 0);
8888       gtk_container_add (GTK_CONTAINER (window), box1);
8889       gtk_widget_show (box1);
8890
8891
8892       box2 = gtk_vbox_new (FALSE, 10);
8893       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8894       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
8895       gtk_widget_show (box2);
8896
8897
8898       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
8899
8900       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
8901       gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
8902       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
8903       gtk_scale_set_digits (GTK_SCALE (scale), 1);
8904       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
8905       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
8906       gtk_widget_show (scale);
8907
8908       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
8909       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
8910                                    GTK_UPDATE_CONTINUOUS);
8911       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
8912       gtk_widget_show (scrollbar);
8913
8914       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
8915       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
8916       g_signal_connect (scale,
8917                         "format_value",
8918                         G_CALLBACK (reformat_value),
8919                         NULL);
8920       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
8921       gtk_widget_show (scale);
8922       
8923       hbox = gtk_hbox_new (FALSE, 0);
8924
8925       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
8926       gtk_widget_set_size_request (scale, -1, 200);
8927       gtk_scale_set_digits (GTK_SCALE (scale), 2);
8928       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
8929       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
8930       gtk_widget_show (scale);
8931
8932       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
8933       gtk_widget_set_size_request (scale, -1, 200);
8934       gtk_scale_set_digits (GTK_SCALE (scale), 2);
8935       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
8936       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
8937       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
8938       gtk_widget_show (scale);
8939
8940       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
8941       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
8942       g_signal_connect (scale,
8943                         "format_value",
8944                         G_CALLBACK (reformat_value),
8945                         NULL);
8946       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
8947       gtk_widget_show (scale);
8948
8949       
8950       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
8951       gtk_widget_show (hbox);
8952       
8953       separator = gtk_hseparator_new ();
8954       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
8955       gtk_widget_show (separator);
8956
8957
8958       box2 = gtk_vbox_new (FALSE, 10);
8959       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8960       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8961       gtk_widget_show (box2);
8962
8963
8964       button = gtk_button_new_with_label ("close");
8965       g_signal_connect_swapped (button, "clicked",
8966                                 G_CALLBACK (gtk_widget_destroy),
8967                                 window);
8968       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8969       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8970       gtk_widget_grab_default (button);
8971       gtk_widget_show (button);
8972     }
8973
8974   if (!GTK_WIDGET_VISIBLE (window))
8975     gtk_widget_show (window);
8976   else
8977     gtk_widget_destroy (window);
8978 }
8979
8980 /*
8981  * GtkRulers
8982  */
8983
8984 void
8985 create_rulers (GtkWidget *widget)
8986 {
8987   static GtkWidget *window = NULL;
8988   GtkWidget *table;
8989   GtkWidget *ruler;
8990
8991   if (!window)
8992     {
8993       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8994
8995       gtk_window_set_screen (GTK_WINDOW (window),
8996                              gtk_widget_get_screen (widget));
8997
8998       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
8999
9000       g_signal_connect (window, "destroy",
9001                         G_CALLBACK (gtk_widget_destroyed),
9002                         &window);
9003
9004       gtk_window_set_title (GTK_WINDOW (window), "rulers");
9005       gtk_widget_set_size_request (window, 300, 300);
9006       gtk_widget_set_events (window, 
9007                              GDK_POINTER_MOTION_MASK 
9008                              | GDK_POINTER_MOTION_HINT_MASK);
9009       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9010
9011       table = gtk_table_new (2, 2, FALSE);
9012       gtk_container_add (GTK_CONTAINER (window), table);
9013       gtk_widget_show (table);
9014
9015       ruler = gtk_hruler_new ();
9016       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
9017       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
9018
9019       g_signal_connect_swapped (window, 
9020                                 "motion_notify_event",
9021                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
9022                                 ruler);
9023       
9024       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
9025                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
9026       gtk_widget_show (ruler);
9027
9028
9029       ruler = gtk_vruler_new ();
9030       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
9031
9032       g_signal_connect_swapped (window, 
9033                                 "motion_notify_event",
9034                                 G_CALLBACK (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
9035                                 ruler);
9036       
9037       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
9038                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
9039       gtk_widget_show (ruler);
9040     }
9041
9042   if (!GTK_WIDGET_VISIBLE (window))
9043     gtk_widget_show (window);
9044   else
9045     gtk_widget_destroy (window);
9046 }
9047
9048 static void
9049 text_toggle_editable (GtkWidget *checkbutton,
9050                        GtkWidget *text)
9051 {
9052    gtk_text_set_editable(GTK_TEXT(text),
9053                           GTK_TOGGLE_BUTTON(checkbutton)->active);
9054 }
9055
9056 static void
9057 text_toggle_word_wrap (GtkWidget *checkbutton,
9058                        GtkWidget *text)
9059 {
9060    gtk_text_set_word_wrap(GTK_TEXT(text),
9061                           GTK_TOGGLE_BUTTON(checkbutton)->active);
9062 }
9063
9064 struct {
9065   GdkColor color;
9066   gchar *name;
9067 } text_colors[] = {
9068  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
9069  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
9070  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
9071  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
9072  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
9073  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
9074  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
9075  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
9076 };
9077
9078 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
9079
9080 /*
9081  * GtkText
9082  */
9083 void
9084 text_insert_random (GtkWidget *w, GtkText *text)
9085 {
9086   int i;
9087   char c;
9088    for (i=0; i<10; i++)
9089     {
9090       c = 'A' + rand() % ('Z' - 'A');
9091       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
9092       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
9093     }
9094 }
9095
9096 void
9097 create_text (GtkWidget *widget)
9098 {
9099   int i, j;
9100
9101   static GtkWidget *window = NULL;
9102   GtkWidget *box1;
9103   GtkWidget *box2;
9104   GtkWidget *hbox;
9105   GtkWidget *button;
9106   GtkWidget *check;
9107   GtkWidget *separator;
9108   GtkWidget *scrolled_window;
9109   GtkWidget *text;
9110
9111   FILE *infile;
9112
9113   if (!window)
9114     {
9115       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9116       gtk_window_set_screen (GTK_WINDOW (window),
9117                              gtk_widget_get_screen (widget));
9118
9119       gtk_widget_set_name (window, "text window");
9120       g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL);
9121       gtk_widget_set_size_request (window, 500, 500);
9122
9123       g_signal_connect (window, "destroy",
9124                         G_CALLBACK (gtk_widget_destroyed),
9125                         &window);
9126
9127       gtk_window_set_title (GTK_WINDOW (window), "test");
9128       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9129
9130
9131       box1 = gtk_vbox_new (FALSE, 0);
9132       gtk_container_add (GTK_CONTAINER (window), box1);
9133       gtk_widget_show (box1);
9134
9135
9136       box2 = gtk_vbox_new (FALSE, 10);
9137       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9138       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
9139       gtk_widget_show (box2);
9140
9141
9142       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
9143       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
9144       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
9145                                       GTK_POLICY_NEVER,
9146                                       GTK_POLICY_ALWAYS);
9147       gtk_widget_show (scrolled_window);
9148
9149       text = gtk_text_new (NULL, NULL);
9150       gtk_text_set_editable (GTK_TEXT (text), TRUE);
9151       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
9152       gtk_widget_grab_focus (text);
9153       gtk_widget_show (text);
9154
9155
9156       gtk_text_freeze (GTK_TEXT (text));
9157
9158       for (i=0; i<ntext_colors; i++)
9159         {
9160           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, 
9161                            text_colors[i].name, -1);
9162           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\t", -1);
9163
9164           for (j=0; j<ntext_colors; j++)
9165             {
9166               gtk_text_insert (GTK_TEXT (text), NULL,
9167                                &text_colors[j].color, &text_colors[i].color,
9168                                "XYZ", -1);
9169             }
9170           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
9171         }
9172
9173       infile = fopen("testgtk.c", "r");
9174       
9175       if (infile)
9176         {
9177           char *buffer;
9178           int nbytes_read, nbytes_alloc;
9179           
9180           nbytes_read = 0;
9181           nbytes_alloc = 1024;
9182           buffer = g_new (char, nbytes_alloc);
9183           while (1)
9184             {
9185               int len;
9186               if (nbytes_alloc < nbytes_read + 1024)
9187                 {
9188                   nbytes_alloc *= 2;
9189                   buffer = g_realloc (buffer, nbytes_alloc);
9190                 }
9191               len = fread (buffer + nbytes_read, 1, 1024, infile);
9192               nbytes_read += len;
9193               if (len < 1024)
9194                 break;
9195             }
9196           
9197           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
9198                            NULL, buffer, nbytes_read);
9199           g_free(buffer);
9200           fclose (infile);
9201         }
9202       
9203       gtk_text_thaw (GTK_TEXT (text));
9204
9205       hbox = gtk_hbutton_box_new ();
9206       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
9207       gtk_widget_show (hbox);
9208
9209       check = gtk_check_button_new_with_label("Editable");
9210       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
9211       g_signal_connect (check, "toggled",
9212                         G_CALLBACK (text_toggle_editable), text);
9213       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
9214       gtk_widget_show (check);
9215
9216       check = gtk_check_button_new_with_label("Wrap Words");
9217       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
9218       g_signal_connect (check, "toggled",
9219                         G_CALLBACK (text_toggle_word_wrap), text);
9220       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
9221       gtk_widget_show (check);
9222
9223       separator = gtk_hseparator_new ();
9224       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9225       gtk_widget_show (separator);
9226
9227
9228       box2 = gtk_vbox_new (FALSE, 10);
9229       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9230       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9231       gtk_widget_show (box2);
9232
9233
9234       button = gtk_button_new_with_label ("insert random");
9235       g_signal_connect (button, "clicked",
9236                         G_CALLBACK (text_insert_random),
9237                         text);
9238       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9239       gtk_widget_show (button);
9240
9241       button = gtk_button_new_with_label ("close");
9242       g_signal_connect_swapped (button, "clicked",
9243                                 G_CALLBACK (gtk_widget_destroy),
9244                                 window);
9245       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9246       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9247       gtk_widget_grab_default (button);
9248       gtk_widget_show (button);
9249     }
9250
9251   if (!GTK_WIDGET_VISIBLE (window))
9252     gtk_widget_show (window);
9253   else
9254     gtk_widget_destroy (window);
9255 }
9256
9257 /*
9258  * GtkNotebook
9259  */
9260
9261 GdkPixbuf *book_open;
9262 GdkPixbuf *book_closed;
9263 GtkWidget *sample_notebook;
9264
9265 static void
9266 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
9267 {
9268   GtkWidget *page_widget;
9269   GtkWidget *pixwid;
9270
9271   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
9272
9273   pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
9274   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
9275   
9276   pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
9277   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
9278 }
9279
9280 static void
9281 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
9282 {
9283   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
9284   gint old_page_num = gtk_notebook_get_current_page (notebook);
9285  
9286   if (page_num == old_page_num)
9287     return;
9288
9289   set_page_image (notebook, page_num, book_open);
9290
9291   if (old_page_num != -1)
9292     set_page_image (notebook, old_page_num, book_closed);
9293 }
9294
9295 static void
9296 tab_fill (GtkToggleButton *button, GtkWidget *child)
9297 {
9298   gboolean expand;
9299   GtkPackType pack_type;
9300
9301   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9302                                         &expand, NULL, &pack_type);
9303   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9304                                       expand, button->active, pack_type);
9305 }
9306
9307 static void
9308 tab_expand (GtkToggleButton *button, GtkWidget *child)
9309 {
9310   gboolean fill;
9311   GtkPackType pack_type;
9312
9313   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9314                                         NULL, &fill, &pack_type);
9315   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9316                                       button->active, fill, pack_type);
9317 }
9318
9319 static void
9320 tab_pack (GtkToggleButton *button, GtkWidget *child)
9321           
9322
9323   gboolean expand;
9324   gboolean fill;
9325
9326   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9327                                         &expand, &fill, NULL);
9328   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
9329                                       expand, fill, button->active);
9330 }
9331
9332 static void
9333 create_pages (GtkNotebook *notebook, gint start, gint end)
9334 {
9335   GtkWidget *child = NULL;
9336   GtkWidget *button;
9337   GtkWidget *label;
9338   GtkWidget *hbox;
9339   GtkWidget *vbox;
9340   GtkWidget *label_box;
9341   GtkWidget *menu_box;
9342   GtkWidget *pixwid;
9343   gint i;
9344   char buffer[32];
9345   char accel_buffer[32];
9346
9347   for (i = start; i <= end; i++)
9348     {
9349       sprintf (buffer, "Page %d", i);
9350       sprintf (accel_buffer, "Page _%d", i);
9351
9352       child = gtk_frame_new (buffer);
9353       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
9354
9355       vbox = gtk_vbox_new (TRUE,0);
9356       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9357       gtk_container_add (GTK_CONTAINER (child), vbox);
9358
9359       hbox = gtk_hbox_new (TRUE,0);
9360       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
9361
9362       button = gtk_check_button_new_with_label ("Fill Tab");
9363       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
9364       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
9365       g_signal_connect (button, "toggled",
9366                         G_CALLBACK (tab_fill), child);
9367
9368       button = gtk_check_button_new_with_label ("Expand Tab");
9369       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
9370       g_signal_connect (button, "toggled",
9371                         G_CALLBACK (tab_expand), child);
9372
9373       button = gtk_check_button_new_with_label ("Pack end");
9374       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
9375       g_signal_connect (button, "toggled",
9376                         G_CALLBACK (tab_pack), child);
9377
9378       button = gtk_button_new_with_label ("Hide Page");
9379       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
9380       g_signal_connect_swapped (button, "clicked",
9381                                 G_CALLBACK (gtk_widget_hide),
9382                                 child);
9383
9384       gtk_widget_show_all (child);
9385
9386       label_box = gtk_hbox_new (FALSE, 0);
9387       pixwid = gtk_image_new_from_pixbuf (book_closed);
9388       g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
9389                            
9390       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
9391       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
9392       label = gtk_label_new_with_mnemonic (accel_buffer);
9393       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
9394       gtk_widget_show_all (label_box);
9395       
9396                                        
9397       menu_box = gtk_hbox_new (FALSE, 0);
9398       pixwid = gtk_image_new_from_pixbuf (book_closed);
9399       g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
9400       
9401       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
9402       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
9403       label = gtk_label_new (buffer);
9404       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
9405       gtk_widget_show_all (menu_box);
9406
9407       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
9408     }
9409 }
9410
9411 static void
9412 rotate_notebook (GtkButton   *button,
9413                  GtkNotebook *notebook)
9414 {
9415   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
9416 }
9417
9418 static void
9419 show_all_pages (GtkButton   *button,
9420                 GtkNotebook *notebook)
9421 {  
9422   gtk_container_foreach (GTK_CONTAINER (notebook),
9423                          (GtkCallback) gtk_widget_show, NULL);
9424 }
9425
9426 static void
9427 notebook_type_changed (GtkWidget *optionmenu,
9428                        gpointer   data)
9429 {
9430   GtkNotebook *notebook;
9431   gint i, c;
9432
9433   enum {
9434     STANDARD,
9435     NOTABS,
9436     BORDERLESS,
9437     SCROLLABLE
9438   };
9439
9440   notebook = GTK_NOTEBOOK (data);
9441
9442   c = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
9443
9444   switch (c)
9445     {
9446     case STANDARD:
9447       /* standard notebook */
9448       gtk_notebook_set_show_tabs (notebook, TRUE);
9449       gtk_notebook_set_show_border (notebook, TRUE);
9450       gtk_notebook_set_scrollable (notebook, FALSE);
9451       break;
9452
9453     case NOTABS:
9454       /* notabs notebook */
9455       gtk_notebook_set_show_tabs (notebook, FALSE);
9456       gtk_notebook_set_show_border (notebook, TRUE);
9457       break;
9458
9459     case BORDERLESS:
9460       /* borderless */
9461       gtk_notebook_set_show_tabs (notebook, FALSE);
9462       gtk_notebook_set_show_border (notebook, FALSE);
9463       break;
9464
9465     case SCROLLABLE:  
9466       /* scrollable */
9467       gtk_notebook_set_show_tabs (notebook, TRUE);
9468       gtk_notebook_set_show_border (notebook, TRUE);
9469       gtk_notebook_set_scrollable (notebook, TRUE);
9470       if (g_list_length (notebook->children) == 5)
9471         create_pages (notebook, 6, 15);
9472       
9473       return;
9474       break;
9475     }
9476   
9477   if (g_list_length (notebook->children) == 15)
9478     for (i = 0; i < 10; i++)
9479       gtk_notebook_remove_page (notebook, 5);
9480 }
9481
9482 static void
9483 notebook_popup (GtkToggleButton *button,
9484                 GtkNotebook     *notebook)
9485 {
9486   if (button->active)
9487     gtk_notebook_popup_enable (notebook);
9488   else
9489     gtk_notebook_popup_disable (notebook);
9490 }
9491
9492 static void
9493 notebook_homogeneous (GtkToggleButton *button,
9494                       GtkNotebook     *notebook)
9495 {
9496   g_object_set (notebook, "homogeneous", button->active, NULL);
9497 }
9498
9499 static void
9500 create_notebook (GtkWidget *widget)
9501 {
9502   static GtkWidget *window = NULL;
9503   GtkWidget *box1;
9504   GtkWidget *box2;
9505   GtkWidget *button;
9506   GtkWidget *separator;
9507   GtkWidget *omenu;
9508   GtkWidget *label;
9509
9510   static gchar *items[] =
9511   {
9512     "Standard",
9513     "No tabs",
9514     "Borderless",
9515     "Scrollable"
9516   };
9517   
9518   if (!window)
9519     {
9520       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9521       gtk_window_set_screen (GTK_WINDOW (window),
9522                              gtk_widget_get_screen (widget));
9523
9524       g_signal_connect (window, "destroy",
9525                         G_CALLBACK (gtk_widget_destroyed),
9526                         &window);
9527
9528       gtk_window_set_title (GTK_WINDOW (window), "notebook");
9529       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9530
9531       box1 = gtk_vbox_new (FALSE, 0);
9532       gtk_container_add (GTK_CONTAINER (window), box1);
9533
9534       sample_notebook = gtk_notebook_new ();
9535       g_signal_connect (sample_notebook, "switch_page",
9536                         G_CALLBACK (page_switch), NULL);
9537       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
9538       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
9539       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
9540
9541       gtk_widget_realize (sample_notebook);
9542
9543       if (!book_open)
9544         book_open = gdk_pixbuf_new_from_xpm_data ((const char **)book_open_xpm);
9545                                                   
9546       if (!book_closed)
9547         book_closed = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
9548
9549       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
9550
9551       separator = gtk_hseparator_new ();
9552       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
9553       
9554       box2 = gtk_hbox_new (FALSE, 5);
9555       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9556       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9557
9558       button = gtk_check_button_new_with_label ("popup menu");
9559       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
9560       g_signal_connect (button, "clicked",
9561                         G_CALLBACK (notebook_popup),
9562                         sample_notebook);
9563
9564       button = gtk_check_button_new_with_label ("homogeneous tabs");
9565       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
9566       g_signal_connect (button, "clicked",
9567                         G_CALLBACK (notebook_homogeneous),
9568                         sample_notebook);
9569
9570       box2 = gtk_hbox_new (FALSE, 5);
9571       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9572       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9573
9574       label = gtk_label_new ("Notebook Style :");
9575       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
9576
9577       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
9578                                  notebook_type_changed,
9579                                  sample_notebook);
9580       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
9581
9582       button = gtk_button_new_with_label ("Show all Pages");
9583       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
9584       g_signal_connect (button, "clicked",
9585                         G_CALLBACK (show_all_pages), sample_notebook);
9586
9587       box2 = gtk_hbox_new (TRUE, 10);
9588       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9589       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9590
9591       button = gtk_button_new_with_label ("prev");
9592       g_signal_connect_swapped (button, "clicked",
9593                                 G_CALLBACK (gtk_notebook_prev_page),
9594                                 sample_notebook);
9595       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9596
9597       button = gtk_button_new_with_label ("next");
9598       g_signal_connect_swapped (button, "clicked",
9599                                 G_CALLBACK (gtk_notebook_next_page),
9600                                 sample_notebook);
9601       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9602
9603       button = gtk_button_new_with_label ("rotate");
9604       g_signal_connect (button, "clicked",
9605                         G_CALLBACK (rotate_notebook), sample_notebook);
9606       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9607
9608       separator = gtk_hseparator_new ();
9609       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
9610
9611       button = gtk_button_new_with_label ("close");
9612       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
9613       g_signal_connect_swapped (button, "clicked",
9614                                 G_CALLBACK (gtk_widget_destroy),
9615                                 window);
9616       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
9617       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9618       gtk_widget_grab_default (button);
9619     }
9620
9621   if (!GTK_WIDGET_VISIBLE (window))
9622     gtk_widget_show_all (window);
9623   else
9624     gtk_widget_destroy (window);
9625 }
9626
9627 /*
9628  * GtkPanes
9629  */
9630
9631 void
9632 toggle_resize (GtkWidget *widget, GtkWidget *child)
9633 {
9634   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
9635   GValue value = { 0, };
9636   g_value_init (&value, G_TYPE_BOOLEAN);
9637   gtk_container_child_get_property (container, child, "resize", &value);
9638   g_value_set_boolean (&value, !g_value_get_boolean (&value));
9639   gtk_container_child_set_property (container, child, "resize", &value);
9640 }
9641
9642 void
9643 toggle_shrink (GtkWidget *widget, GtkWidget *child)
9644 {
9645   GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
9646   GValue value = { 0, };
9647   g_value_init (&value, G_TYPE_BOOLEAN);
9648   gtk_container_child_get_property (container, child, "shrink", &value);
9649   g_value_set_boolean (&value, !g_value_get_boolean (&value));
9650   gtk_container_child_set_property (container, child, "shrink", &value);
9651 }
9652
9653 static void
9654 paned_props_clicked (GtkWidget *button,
9655                      GObject   *paned)
9656 {
9657   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
9658   
9659   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
9660 }
9661
9662 GtkWidget *
9663 create_pane_options (GtkPaned    *paned,
9664                      const gchar *frame_label,
9665                      const gchar *label1,
9666                      const gchar *label2)
9667 {
9668   GtkWidget *frame;
9669   GtkWidget *table;
9670   GtkWidget *label;
9671   GtkWidget *button;
9672   GtkWidget *check_button;
9673   
9674   frame = gtk_frame_new (frame_label);
9675   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
9676   
9677   table = gtk_table_new (4, 2, 4);
9678   gtk_container_add (GTK_CONTAINER (frame), table);
9679   
9680   label = gtk_label_new (label1);
9681   gtk_table_attach_defaults (GTK_TABLE (table), label,
9682                              0, 1, 0, 1);
9683   
9684   check_button = gtk_check_button_new_with_label ("Resize");
9685   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
9686                              0, 1, 1, 2);
9687   g_signal_connect (check_button, "toggled",
9688                     G_CALLBACK (toggle_resize),
9689                     paned->child1);
9690   
9691   check_button = gtk_check_button_new_with_label ("Shrink");
9692   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
9693                              0, 1, 2, 3);
9694   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
9695                                TRUE);
9696   g_signal_connect (check_button, "toggled",
9697                     G_CALLBACK (toggle_shrink),
9698                     paned->child1);
9699   
9700   label = gtk_label_new (label2);
9701   gtk_table_attach_defaults (GTK_TABLE (table), label,
9702                              1, 2, 0, 1);
9703   
9704   check_button = gtk_check_button_new_with_label ("Resize");
9705   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
9706                              1, 2, 1, 2);
9707   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
9708                                TRUE);
9709   g_signal_connect (check_button, "toggled",
9710                     G_CALLBACK (toggle_resize),
9711                     paned->child2);
9712   
9713   check_button = gtk_check_button_new_with_label ("Shrink");
9714   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
9715                              1, 2, 2, 3);
9716   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
9717                                TRUE);
9718   g_signal_connect (check_button, "toggled",
9719                     G_CALLBACK (toggle_shrink),
9720                     paned->child2);
9721
9722   button = gtk_button_new_with_mnemonic ("_Properties");
9723   gtk_table_attach_defaults (GTK_TABLE (table), button,
9724                              0, 2, 3, 4);
9725   g_signal_connect (button, "clicked",
9726                     G_CALLBACK (paned_props_clicked),
9727                     paned);
9728
9729   return frame;
9730 }
9731
9732 void
9733 create_panes (GtkWidget *widget)
9734 {
9735   static GtkWidget *window = NULL;
9736   GtkWidget *frame;
9737   GtkWidget *hpaned;
9738   GtkWidget *vpaned;
9739   GtkWidget *button;
9740   GtkWidget *vbox;
9741
9742   if (!window)
9743     {
9744       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9745
9746       gtk_window_set_screen (GTK_WINDOW (window),
9747                              gtk_widget_get_screen (widget));
9748       
9749       g_signal_connect (window, "destroy",
9750                         G_CALLBACK (gtk_widget_destroyed),
9751                         &window);
9752
9753       gtk_window_set_title (GTK_WINDOW (window), "Panes");
9754       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9755
9756       vbox = gtk_vbox_new (FALSE, 0);
9757       gtk_container_add (GTK_CONTAINER (window), vbox);
9758       
9759       vpaned = gtk_vpaned_new ();
9760       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
9761       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
9762
9763       hpaned = gtk_hpaned_new ();
9764       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
9765
9766       frame = gtk_frame_new (NULL);
9767       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
9768       gtk_widget_set_size_request (frame, 60, 60);
9769       gtk_paned_add1 (GTK_PANED (hpaned), frame);
9770       
9771       button = gtk_button_new_with_label ("Hi there");
9772       gtk_container_add (GTK_CONTAINER(frame), button);
9773
9774       frame = gtk_frame_new (NULL);
9775       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
9776       gtk_widget_set_size_request (frame, 80, 60);
9777       gtk_paned_add2 (GTK_PANED (hpaned), frame);
9778
9779       frame = gtk_frame_new (NULL);
9780       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
9781       gtk_widget_set_size_request (frame, 60, 80);
9782       gtk_paned_add2 (GTK_PANED (vpaned), frame);
9783
9784       /* Now create toggle buttons to control sizing */
9785
9786       gtk_box_pack_start (GTK_BOX (vbox),
9787                           create_pane_options (GTK_PANED (hpaned),
9788                                                "Horizontal",
9789                                                "Left",
9790                                                "Right"),
9791                           FALSE, FALSE, 0);
9792
9793       gtk_box_pack_start (GTK_BOX (vbox),
9794                           create_pane_options (GTK_PANED (vpaned),
9795                                                "Vertical",
9796                                                "Top",
9797                                                "Bottom"),
9798                           FALSE, FALSE, 0);
9799
9800       gtk_widget_show_all (vbox);
9801     }
9802
9803   if (!GTK_WIDGET_VISIBLE (window))
9804     gtk_widget_show (window);
9805   else
9806     gtk_widget_destroy (window);
9807 }
9808
9809 /*
9810  * Paned keyboard navigation
9811  */
9812
9813 static GtkWidget*
9814 paned_keyboard_window1 (GtkWidget *widget)
9815 {
9816   GtkWidget *window1;
9817   GtkWidget *hpaned1;
9818   GtkWidget *frame1;
9819   GtkWidget *vbox1;
9820   GtkWidget *button7;
9821   GtkWidget *button8;
9822   GtkWidget *button9;
9823   GtkWidget *vpaned1;
9824   GtkWidget *frame2;
9825   GtkWidget *frame5;
9826   GtkWidget *hbox1;
9827   GtkWidget *button5;
9828   GtkWidget *button6;
9829   GtkWidget *frame3;
9830   GtkWidget *frame4;
9831   GtkWidget *table1;
9832   GtkWidget *button1;
9833   GtkWidget *button2;
9834   GtkWidget *button3;
9835   GtkWidget *button4;
9836
9837   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9838   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
9839   gtk_window_set_screen (GTK_WINDOW (window1), 
9840                          gtk_widget_get_screen (widget));
9841
9842   hpaned1 = gtk_hpaned_new ();
9843   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
9844
9845   frame1 = gtk_frame_new (NULL);
9846   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
9847   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
9848
9849   vbox1 = gtk_vbox_new (FALSE, 0);
9850   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
9851
9852   button7 = gtk_button_new_with_label ("button7");
9853   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
9854
9855   button8 = gtk_button_new_with_label ("button8");
9856   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
9857
9858   button9 = gtk_button_new_with_label ("button9");
9859   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
9860
9861   vpaned1 = gtk_vpaned_new ();
9862   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
9863
9864   frame2 = gtk_frame_new (NULL);
9865   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
9866   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
9867
9868   frame5 = gtk_frame_new (NULL);
9869   gtk_container_add (GTK_CONTAINER (frame2), frame5);
9870
9871   hbox1 = gtk_hbox_new (FALSE, 0);
9872   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
9873
9874   button5 = gtk_button_new_with_label ("button5");
9875   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
9876
9877   button6 = gtk_button_new_with_label ("button6");
9878   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
9879
9880   frame3 = gtk_frame_new (NULL);
9881   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
9882   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
9883
9884   frame4 = gtk_frame_new ("Buttons");
9885   gtk_container_add (GTK_CONTAINER (frame3), frame4);
9886   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
9887
9888   table1 = gtk_table_new (2, 2, FALSE);
9889   gtk_container_add (GTK_CONTAINER (frame4), table1);
9890   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
9891
9892   button1 = gtk_button_new_with_label ("button1");
9893   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
9894                     (GtkAttachOptions) (GTK_FILL),
9895                     (GtkAttachOptions) (0), 0, 0);
9896
9897   button2 = gtk_button_new_with_label ("button2");
9898   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
9899                     (GtkAttachOptions) (GTK_FILL),
9900                     (GtkAttachOptions) (0), 0, 0);
9901
9902   button3 = gtk_button_new_with_label ("button3");
9903   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
9904                     (GtkAttachOptions) (GTK_FILL),
9905                     (GtkAttachOptions) (0), 0, 0);
9906
9907   button4 = gtk_button_new_with_label ("button4");
9908   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
9909                     (GtkAttachOptions) (GTK_FILL),
9910                     (GtkAttachOptions) (0), 0, 0);
9911
9912   return window1;
9913 }
9914
9915 static GtkWidget*
9916 paned_keyboard_window2 (GtkWidget *widget)
9917 {
9918   GtkWidget *window2;
9919   GtkWidget *hpaned2;
9920   GtkWidget *frame6;
9921   GtkWidget *button13;
9922   GtkWidget *hbox2;
9923   GtkWidget *vpaned2;
9924   GtkWidget *frame7;
9925   GtkWidget *button12;
9926   GtkWidget *frame8;
9927   GtkWidget *button11;
9928   GtkWidget *button10;
9929
9930   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9931   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
9932
9933   gtk_window_set_screen (GTK_WINDOW (window2), 
9934                          gtk_widget_get_screen (widget));
9935
9936   hpaned2 = gtk_hpaned_new ();
9937   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
9938
9939   frame6 = gtk_frame_new (NULL);
9940   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
9941   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
9942
9943   button13 = gtk_button_new_with_label ("button13");
9944   gtk_container_add (GTK_CONTAINER (frame6), button13);
9945
9946   hbox2 = gtk_hbox_new (FALSE, 0);
9947   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
9948
9949   vpaned2 = gtk_vpaned_new ();
9950   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
9951
9952   frame7 = gtk_frame_new (NULL);
9953   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
9954   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
9955
9956   button12 = gtk_button_new_with_label ("button12");
9957   gtk_container_add (GTK_CONTAINER (frame7), button12);
9958
9959   frame8 = gtk_frame_new (NULL);
9960   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
9961   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
9962
9963   button11 = gtk_button_new_with_label ("button11");
9964   gtk_container_add (GTK_CONTAINER (frame8), button11);
9965
9966   button10 = gtk_button_new_with_label ("button10");
9967   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
9968
9969   return window2;
9970 }
9971
9972 static GtkWidget*
9973 paned_keyboard_window3 (GtkWidget *widget)
9974 {
9975   GtkWidget *window3;
9976   GtkWidget *vbox2;
9977   GtkWidget *label1;
9978   GtkWidget *hpaned3;
9979   GtkWidget *frame9;
9980   GtkWidget *button14;
9981   GtkWidget *hpaned4;
9982   GtkWidget *frame10;
9983   GtkWidget *button15;
9984   GtkWidget *hpaned5;
9985   GtkWidget *frame11;
9986   GtkWidget *button16;
9987   GtkWidget *frame12;
9988   GtkWidget *button17;
9989
9990   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9991   g_object_set_data (G_OBJECT (window3), "window3", window3);
9992   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
9993
9994   gtk_window_set_screen (GTK_WINDOW (window3), 
9995                          gtk_widget_get_screen (widget));
9996   
9997
9998   vbox2 = gtk_vbox_new (FALSE, 0);
9999   gtk_container_add (GTK_CONTAINER (window3), vbox2);
10000
10001   label1 = gtk_label_new ("Three panes nested inside each other");
10002   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
10003
10004   hpaned3 = gtk_hpaned_new ();
10005   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
10006
10007   frame9 = gtk_frame_new (NULL);
10008   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
10009   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
10010
10011   button14 = gtk_button_new_with_label ("button14");
10012   gtk_container_add (GTK_CONTAINER (frame9), button14);
10013
10014   hpaned4 = gtk_hpaned_new ();
10015   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
10016
10017   frame10 = gtk_frame_new (NULL);
10018   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
10019   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
10020
10021   button15 = gtk_button_new_with_label ("button15");
10022   gtk_container_add (GTK_CONTAINER (frame10), button15);
10023
10024   hpaned5 = gtk_hpaned_new ();
10025   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
10026
10027   frame11 = gtk_frame_new (NULL);
10028   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
10029   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
10030
10031   button16 = gtk_button_new_with_label ("button16");
10032   gtk_container_add (GTK_CONTAINER (frame11), button16);
10033
10034   frame12 = gtk_frame_new (NULL);
10035   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
10036   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
10037
10038   button17 = gtk_button_new_with_label ("button17");
10039   gtk_container_add (GTK_CONTAINER (frame12), button17);
10040
10041   return window3;
10042 }
10043
10044 static GtkWidget*
10045 paned_keyboard_window4 (GtkWidget *widget)
10046 {
10047   GtkWidget *window4;
10048   GtkWidget *vbox3;
10049   GtkWidget *label2;
10050   GtkWidget *hpaned6;
10051   GtkWidget *vpaned3;
10052   GtkWidget *button19;
10053   GtkWidget *button18;
10054   GtkWidget *hbox3;
10055   GtkWidget *vpaned4;
10056   GtkWidget *button21;
10057   GtkWidget *button20;
10058   GtkWidget *vpaned5;
10059   GtkWidget *button23;
10060   GtkWidget *button22;
10061   GtkWidget *vpaned6;
10062   GtkWidget *button25;
10063   GtkWidget *button24;
10064
10065   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10066   g_object_set_data (G_OBJECT (window4), "window4", window4);
10067   gtk_window_set_title (GTK_WINDOW (window4), "window4");
10068
10069   gtk_window_set_screen (GTK_WINDOW (window4), 
10070                          gtk_widget_get_screen (widget));
10071
10072   vbox3 = gtk_vbox_new (FALSE, 0);
10073   gtk_container_add (GTK_CONTAINER (window4), vbox3);
10074
10075   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
10076   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
10077   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
10078
10079   hpaned6 = gtk_hpaned_new ();
10080   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
10081
10082   vpaned3 = gtk_vpaned_new ();
10083   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
10084
10085   button19 = gtk_button_new_with_label ("button19");
10086   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
10087
10088   button18 = gtk_button_new_with_label ("button18");
10089   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
10090
10091   hbox3 = gtk_hbox_new (FALSE, 0);
10092   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
10093
10094   vpaned4 = gtk_vpaned_new ();
10095   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
10096
10097   button21 = gtk_button_new_with_label ("button21");
10098   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
10099
10100   button20 = gtk_button_new_with_label ("button20");
10101   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
10102
10103   vpaned5 = gtk_vpaned_new ();
10104   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
10105
10106   button23 = gtk_button_new_with_label ("button23");
10107   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
10108
10109   button22 = gtk_button_new_with_label ("button22");
10110   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
10111
10112   vpaned6 = gtk_vpaned_new ();
10113   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
10114
10115   button25 = gtk_button_new_with_label ("button25");
10116   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
10117
10118   button24 = gtk_button_new_with_label ("button24");
10119   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
10120
10121   return window4;
10122 }
10123
10124 static void
10125 create_paned_keyboard_navigation (GtkWidget *widget)
10126 {
10127   static GtkWidget *window1 = NULL;
10128   static GtkWidget *window2 = NULL;
10129   static GtkWidget *window3 = NULL;
10130   static GtkWidget *window4 = NULL;
10131
10132   if (window1 && 
10133      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
10134     {
10135       gtk_widget_destroy (window1);
10136       gtk_widget_destroy (window2);
10137       gtk_widget_destroy (window3);
10138       gtk_widget_destroy (window4);
10139     }
10140   
10141   if (!window1)
10142     {
10143       window1 = paned_keyboard_window1 (widget);
10144       g_signal_connect (window1, "destroy",
10145                         G_CALLBACK (gtk_widget_destroyed),
10146                         &window1);
10147     }
10148
10149   if (!window2)
10150     {
10151       window2 = paned_keyboard_window2 (widget);
10152       g_signal_connect (window2, "destroy",
10153                         G_CALLBACK (gtk_widget_destroyed),
10154                         &window2);
10155     }
10156
10157   if (!window3)
10158     {
10159       window3 = paned_keyboard_window3 (widget);
10160       g_signal_connect (window3, "destroy",
10161                         G_CALLBACK (gtk_widget_destroyed),
10162                         &window3);
10163     }
10164
10165   if (!window4)
10166     {
10167       window4 = paned_keyboard_window4 (widget);
10168       g_signal_connect (window4, "destroy",
10169                         G_CALLBACK (gtk_widget_destroyed),
10170                         &window4);
10171     }
10172
10173   if (GTK_WIDGET_VISIBLE (window1))
10174     gtk_widget_destroy (GTK_WIDGET (window1));
10175   else
10176     gtk_widget_show_all (GTK_WIDGET (window1));
10177
10178   if (GTK_WIDGET_VISIBLE (window2))
10179     gtk_widget_destroy (GTK_WIDGET (window2));
10180   else
10181     gtk_widget_show_all (GTK_WIDGET (window2));
10182
10183   if (GTK_WIDGET_VISIBLE (window3))
10184     gtk_widget_destroy (GTK_WIDGET (window3));
10185   else
10186     gtk_widget_show_all (GTK_WIDGET (window3));
10187
10188   if (GTK_WIDGET_VISIBLE (window4))
10189     gtk_widget_destroy (GTK_WIDGET (window4));
10190   else
10191     gtk_widget_show_all (GTK_WIDGET (window4));
10192 }
10193
10194
10195 /*
10196  * Shaped Windows
10197  */
10198
10199 typedef struct _cursoroffset {gint x,y;} CursorOffset;
10200
10201 static void
10202 shape_pressed (GtkWidget *widget, GdkEventButton *event)
10203 {
10204   CursorOffset *p;
10205
10206   /* ignore double and triple click */
10207   if (event->type != GDK_BUTTON_PRESS)
10208     return;
10209
10210   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
10211   p->x = (int) event->x;
10212   p->y = (int) event->y;
10213
10214   gtk_grab_add (widget);
10215   gdk_pointer_grab (widget->window, TRUE,
10216                     GDK_BUTTON_RELEASE_MASK |
10217                     GDK_BUTTON_MOTION_MASK |
10218                     GDK_POINTER_MOTION_HINT_MASK,
10219                     NULL, NULL, 0);
10220 }
10221
10222 static void
10223 shape_released (GtkWidget *widget)
10224 {
10225   gtk_grab_remove (widget);
10226   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
10227                               GDK_CURRENT_TIME);
10228 }
10229
10230 static void
10231 shape_motion (GtkWidget      *widget, 
10232               GdkEventMotion *event)
10233 {
10234   gint xp, yp;
10235   CursorOffset * p;
10236   GdkModifierType mask;
10237
10238   p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
10239
10240   /*
10241    * Can't use event->x / event->y here 
10242    * because I need absolute coordinates.
10243    */
10244   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
10245   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
10246 }
10247
10248 GtkWidget *
10249 shape_create_icon (GdkScreen *screen,
10250                    char      *xpm_file,
10251                    gint       x,
10252                    gint       y,
10253                    gint       px,
10254                    gint       py,
10255                    gint       window_type)
10256 {
10257   GtkWidget *window;
10258   GtkWidget *pixmap;
10259   GtkWidget *fixed;
10260   CursorOffset* icon_pos;
10261   GdkGC* gc;
10262   GdkBitmap *gdk_pixmap_mask;
10263   GdkPixmap *gdk_pixmap;
10264   GtkStyle *style;
10265
10266   style = gtk_widget_get_default_style ();
10267   gc = style->black_gc; 
10268
10269   /*
10270    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
10271    */
10272   window = gtk_window_new (window_type);
10273   gtk_window_set_screen (GTK_WINDOW (window), screen);
10274   
10275   fixed = gtk_fixed_new ();
10276   gtk_widget_set_size_request (fixed, 100, 100);
10277   gtk_container_add (GTK_CONTAINER (window), fixed);
10278   gtk_widget_show (fixed);
10279   
10280   gtk_widget_set_events (window, 
10281                          gtk_widget_get_events (window) |
10282                          GDK_BUTTON_MOTION_MASK |
10283                          GDK_POINTER_MOTION_HINT_MASK |
10284                          GDK_BUTTON_PRESS_MASK);
10285
10286   gtk_widget_realize (window);
10287   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
10288                                            &style->bg[GTK_STATE_NORMAL],
10289                                            xpm_file);
10290
10291   pixmap = gtk_image_new_from_pixmap (gdk_pixmap, gdk_pixmap_mask);
10292   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
10293   gtk_widget_show (pixmap);
10294   
10295   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
10296   
10297   g_object_unref (gdk_pixmap_mask);
10298   g_object_unref (gdk_pixmap);
10299
10300   g_signal_connect (window, "button_press_event",
10301                     G_CALLBACK (shape_pressed), NULL);
10302   g_signal_connect (window, "button_release_event",
10303                     G_CALLBACK (shape_released), NULL);
10304   g_signal_connect (window, "motion_notify_event",
10305                     G_CALLBACK (shape_motion), NULL);
10306
10307   icon_pos = g_new (CursorOffset, 1);
10308   g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
10309
10310   gtk_widget_set_uposition (window, x, y);
10311   gtk_widget_show (window);
10312   
10313   return window;
10314 }
10315
10316 void 
10317 create_shapes (GtkWidget *widget)
10318 {
10319   /* Variables used by the Drag/Drop and Shape Window demos */
10320   static GtkWidget *modeller = NULL;
10321   static GtkWidget *sheets = NULL;
10322   static GtkWidget *rings = NULL;
10323   static GtkWidget *with_region = NULL;
10324   GdkScreen *screen = gtk_widget_get_screen (widget);
10325   
10326   if (!(file_exists ("Modeller.xpm") &&
10327         file_exists ("FilesQueue.xpm") &&
10328         file_exists ("3DRings.xpm")))
10329     return;
10330   
10331
10332   if (!modeller)
10333     {
10334       modeller = shape_create_icon (screen, "Modeller.xpm",
10335                                     440, 140, 0,0, GTK_WINDOW_POPUP);
10336
10337       g_signal_connect (modeller, "destroy",
10338                         G_CALLBACK (gtk_widget_destroyed),
10339                         &modeller);
10340     }
10341   else
10342     gtk_widget_destroy (modeller);
10343
10344   if (!sheets)
10345     {
10346       sheets = shape_create_icon (screen, "FilesQueue.xpm",
10347                                   580, 170, 0,0, GTK_WINDOW_POPUP);
10348
10349       g_signal_connect (sheets, "destroy",
10350                         G_CALLBACK (gtk_widget_destroyed),
10351                         &sheets);
10352
10353     }
10354   else
10355     gtk_widget_destroy (sheets);
10356
10357   if (!rings)
10358     {
10359       rings = shape_create_icon (screen, "3DRings.xpm",
10360                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
10361
10362       g_signal_connect (rings, "destroy",
10363                         G_CALLBACK (gtk_widget_destroyed),
10364                         &rings);
10365     }
10366   else
10367     gtk_widget_destroy (rings);
10368
10369   if (!with_region)
10370     {
10371       GdkRegion *region;
10372       gint x, y;
10373       
10374       with_region = shape_create_icon (screen, "3DRings.xpm",
10375                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
10376
10377       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
10378       
10379       g_signal_connect (with_region, "destroy",
10380                         G_CALLBACK (gtk_widget_destroyed),
10381                         &with_region);
10382
10383       /* reset shape from mask to a region */
10384       x = 0;
10385       y = 0;
10386       region = gdk_region_new ();
10387
10388       while (x < 460)
10389         {
10390           while (y < 270)
10391             {
10392               GdkRectangle rect;
10393               rect.x = x;
10394               rect.y = y;
10395               rect.width = 10;
10396               rect.height = 10;
10397
10398               gdk_region_union_with_rect (region, &rect);
10399               
10400               y += 20;
10401             }
10402           y = 0;
10403           x += 20;
10404         }
10405
10406       gdk_window_shape_combine_region (with_region->window,
10407                                        region,
10408                                        0, 0);
10409     }
10410   else
10411     gtk_widget_destroy (with_region);
10412 }
10413
10414 /*
10415  * WM Hints demo
10416  */
10417
10418 void
10419 create_wmhints (GtkWidget *widget)
10420 {
10421   static GtkWidget *window = NULL;
10422   GtkWidget *label;
10423   GtkWidget *separator;
10424   GtkWidget *button;
10425   GtkWidget *box1;
10426   GtkWidget *box2;
10427
10428   GdkBitmap *circles;
10429
10430   if (!window)
10431     {
10432       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10433
10434       gtk_window_set_screen (GTK_WINDOW (window),
10435                              gtk_widget_get_screen (widget));
10436       
10437       g_signal_connect (window, "destroy",
10438                         G_CALLBACK (gtk_widget_destroyed),
10439                         &window);
10440
10441       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
10442       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10443
10444       gtk_widget_realize (window);
10445       
10446       circles = gdk_bitmap_create_from_data (window->window,
10447                                              circles_bits,
10448                                              circles_width,
10449                                              circles_height);
10450       gdk_window_set_icon (window->window, NULL,
10451                            circles, circles);
10452       
10453       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
10454   
10455       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
10456       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
10457       
10458       box1 = gtk_vbox_new (FALSE, 0);
10459       gtk_container_add (GTK_CONTAINER (window), box1);
10460       gtk_widget_show (box1);
10461
10462       label = gtk_label_new ("Try iconizing me!");
10463       gtk_widget_set_size_request (label, 150, 50);
10464       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
10465       gtk_widget_show (label);
10466
10467
10468       separator = gtk_hseparator_new ();
10469       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
10470       gtk_widget_show (separator);
10471
10472
10473       box2 = gtk_vbox_new (FALSE, 10);
10474       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
10475       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
10476       gtk_widget_show (box2);
10477
10478
10479       button = gtk_button_new_with_label ("close");
10480
10481       g_signal_connect_swapped (button, "clicked",
10482                                 G_CALLBACK (gtk_widget_destroy),
10483                                 window);
10484
10485       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
10486       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10487       gtk_widget_grab_default (button);
10488       gtk_widget_show (button);
10489     }
10490
10491   if (!GTK_WIDGET_VISIBLE (window))
10492     gtk_widget_show (window);
10493   else
10494     gtk_widget_destroy (window);
10495 }
10496
10497
10498 /*
10499  * Window state tracking
10500  */
10501
10502 static gint
10503 window_state_callback (GtkWidget *widget,
10504                        GdkEventWindowState *event,
10505                        gpointer data)
10506 {
10507   GtkWidget *label = data;
10508   gchar *msg;
10509
10510   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
10511                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
10512                      "withdrawn" : "not withdrawn", ", ",
10513                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
10514                      "iconified" : "not iconified", ", ",
10515                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
10516                      "sticky" : "not sticky", ", ",
10517                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
10518                      "maximized" : "not maximized", ", ",
10519                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
10520                      "fullscreen" : "not fullscreen",
10521                      (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
10522                      "above" : "not above", ", ",
10523                      (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
10524                      "below" : "not below", ", ",
10525                      NULL);
10526   
10527   gtk_label_set_text (GTK_LABEL (label), msg);
10528
10529   g_free (msg);
10530
10531   return FALSE;
10532 }
10533
10534 static GtkWidget*
10535 tracking_label (GtkWidget *window)
10536 {
10537   GtkWidget *label;
10538   GtkWidget *hbox;
10539   GtkWidget *button;
10540
10541   hbox = gtk_hbox_new (FALSE, 5);
10542
10543   g_signal_connect_object (hbox,
10544                            "destroy",
10545                            G_CALLBACK (gtk_widget_destroy),
10546                            window,
10547                            G_CONNECT_SWAPPED);
10548   
10549   label = gtk_label_new ("<no window state events received>");
10550   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
10551   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
10552   
10553   g_signal_connect (window,
10554                     "window_state_event",
10555                     G_CALLBACK (window_state_callback),
10556                     label);
10557
10558   button = gtk_button_new_with_label ("Deiconify");
10559   g_signal_connect_object (button,
10560                            "clicked",
10561                            G_CALLBACK (gtk_window_deiconify),
10562                            window,
10563                            G_CONNECT_SWAPPED);
10564   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10565
10566   button = gtk_button_new_with_label ("Iconify");
10567   g_signal_connect_object (button,
10568                            "clicked",
10569                            G_CALLBACK (gtk_window_iconify),
10570                            window,
10571                            G_CONNECT_SWAPPED);
10572   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10573
10574   button = gtk_button_new_with_label ("Fullscreen");
10575   g_signal_connect_object (button,
10576                            "clicked",
10577                            G_CALLBACK (gtk_window_fullscreen),
10578                            window,
10579                            G_CONNECT_SWAPPED);
10580   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10581
10582   button = gtk_button_new_with_label ("Unfullscreen");
10583   g_signal_connect_object (button,
10584                            "clicked",
10585                            G_CALLBACK (gtk_window_unfullscreen),
10586                            window,
10587                            G_CONNECT_SWAPPED);
10588   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10589   
10590   button = gtk_button_new_with_label ("Present");
10591   g_signal_connect_object (button,
10592                            "clicked",
10593                            G_CALLBACK (gtk_window_present),
10594                            window,
10595                            G_CONNECT_SWAPPED);
10596   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10597
10598   button = gtk_button_new_with_label ("Show");
10599   g_signal_connect_object (button,
10600                            "clicked",
10601                            G_CALLBACK (gtk_widget_show),
10602                            window,
10603                            G_CONNECT_SWAPPED);
10604   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
10605   
10606   gtk_widget_show_all (hbox);
10607   
10608   return hbox;
10609 }
10610
10611 void
10612 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
10613 {
10614   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
10615
10616   gtk_window_set_keep_above (GTK_WINDOW (data),
10617                              gtk_toggle_button_get_active (togglebutton));
10618
10619   if (gtk_toggle_button_get_active (togglebutton))
10620     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
10621 }
10622
10623 void
10624 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
10625 {
10626   GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
10627
10628   gtk_window_set_keep_below (GTK_WINDOW (data),
10629                              gtk_toggle_button_get_active (togglebutton));
10630
10631   if (gtk_toggle_button_get_active (togglebutton))
10632     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
10633 }
10634
10635
10636 static GtkWidget*
10637 get_state_controls (GtkWidget *window)
10638 {
10639   GtkWidget *vbox;
10640   GtkWidget *button;
10641   GtkWidget *button_above;
10642   GtkWidget *button_below;
10643
10644   vbox = gtk_vbox_new (FALSE, 0);
10645   
10646   button = gtk_button_new_with_label ("Stick");
10647   g_signal_connect_object (button,
10648                            "clicked",
10649                            G_CALLBACK (gtk_window_stick),
10650                            window,
10651                            G_CONNECT_SWAPPED);
10652   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10653
10654   button = gtk_button_new_with_label ("Unstick");
10655   g_signal_connect_object (button,
10656                            "clicked",
10657                            G_CALLBACK (gtk_window_unstick),
10658                            window,
10659                            G_CONNECT_SWAPPED);
10660   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10661   
10662   button = gtk_button_new_with_label ("Maximize");
10663   g_signal_connect_object (button,
10664                            "clicked",
10665                            G_CALLBACK (gtk_window_maximize),
10666                            window,
10667                            G_CONNECT_SWAPPED);
10668   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10669
10670   button = gtk_button_new_with_label ("Unmaximize");
10671   g_signal_connect_object (button,
10672                            "clicked",
10673                            G_CALLBACK (gtk_window_unmaximize),
10674                            window,
10675                            G_CONNECT_SWAPPED);
10676   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10677
10678   button = gtk_button_new_with_label ("Iconify");
10679   g_signal_connect_object (button,
10680                            "clicked",
10681                            G_CALLBACK (gtk_window_iconify),
10682                            window,
10683                            G_CONNECT_SWAPPED);
10684   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10685
10686   button = gtk_button_new_with_label ("Fullscreen");
10687   g_signal_connect_object (button,
10688                            "clicked",
10689                            G_CALLBACK (gtk_window_fullscreen),
10690                            window,
10691                            G_CONNECT_SWAPPED);
10692   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10693
10694   button = gtk_button_new_with_label ("Unfullscreen");
10695   g_signal_connect_object (button,
10696                            "clicked",
10697                            G_CALLBACK (gtk_window_unfullscreen),
10698                            window,
10699                            G_CONNECT_SWAPPED);
10700   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10701
10702   button_above = gtk_toggle_button_new_with_label ("Keep above");
10703   g_signal_connect (button_above,
10704                     "toggled",
10705                     G_CALLBACK (keep_window_above),
10706                     window);
10707   gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
10708
10709   button_below = gtk_toggle_button_new_with_label ("Keep below");
10710   g_signal_connect (button_below,
10711                     "toggled",
10712                     G_CALLBACK (keep_window_below),
10713                     window);
10714   gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
10715
10716   g_object_set_data (G_OBJECT (button_above), "radio", button_below);
10717   g_object_set_data (G_OBJECT (button_below), "radio", button_above);
10718
10719   button = gtk_button_new_with_label ("Hide (withdraw)");
10720   g_signal_connect_object (button,
10721                            "clicked",
10722                            G_CALLBACK (gtk_widget_hide),
10723                            window,
10724                            G_CONNECT_SWAPPED);
10725   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10726   
10727   gtk_widget_show_all (vbox);
10728
10729   return vbox;
10730 }
10731
10732 void
10733 create_window_states (GtkWidget *widget)
10734 {
10735   static GtkWidget *window = NULL;
10736   GtkWidget *label;
10737   GtkWidget *box1;
10738   GtkWidget *iconified;
10739   GtkWidget *normal;
10740   GtkWidget *controls;
10741
10742   if (!window)
10743     {
10744       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10745       gtk_window_set_screen (GTK_WINDOW (window),
10746                              gtk_widget_get_screen (widget));
10747
10748       g_signal_connect (window, "destroy",
10749                         G_CALLBACK (gtk_widget_destroyed),
10750                         &window);
10751
10752       gtk_window_set_title (GTK_WINDOW (window), "Window states");
10753       
10754       box1 = gtk_vbox_new (FALSE, 0);
10755       gtk_container_add (GTK_CONTAINER (window), box1);
10756
10757       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10758
10759       gtk_window_set_screen (GTK_WINDOW (iconified),
10760                              gtk_widget_get_screen (widget));
10761       
10762       g_signal_connect_object (iconified, "destroy",
10763                                G_CALLBACK (gtk_widget_destroy),
10764                                window,
10765                                G_CONNECT_SWAPPED);
10766       gtk_window_iconify (GTK_WINDOW (iconified));
10767       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
10768       controls = get_state_controls (iconified);
10769       gtk_container_add (GTK_CONTAINER (iconified), controls);
10770       
10771       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10772
10773       gtk_window_set_screen (GTK_WINDOW (normal),
10774                              gtk_widget_get_screen (widget));
10775       
10776       g_signal_connect_object (normal, "destroy",
10777                                G_CALLBACK (gtk_widget_destroy),
10778                                window,
10779                                G_CONNECT_SWAPPED);
10780       
10781       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
10782       controls = get_state_controls (normal);
10783       gtk_container_add (GTK_CONTAINER (normal), controls);
10784       
10785       label = tracking_label (iconified);
10786       gtk_container_add (GTK_CONTAINER (box1), label);
10787
10788       label = tracking_label (normal);
10789       gtk_container_add (GTK_CONTAINER (box1), label);
10790
10791       gtk_widget_show_all (iconified);
10792       gtk_widget_show_all (normal);
10793       gtk_widget_show_all (box1);
10794     }
10795
10796   if (!GTK_WIDGET_VISIBLE (window))
10797     gtk_widget_show (window);
10798   else
10799     gtk_widget_destroy (window);
10800 }
10801
10802 /*
10803  * Window sizing
10804  */
10805
10806 static gint
10807 configure_event_callback (GtkWidget *widget,
10808                           GdkEventConfigure *event,
10809                           gpointer data)
10810 {
10811   GtkWidget *label = data;
10812   gchar *msg;
10813   gint x, y;
10814   
10815   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
10816   
10817   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
10818                          "position: %d, %d",
10819                          event->x, event->y, event->width, event->height,
10820                          x, y);
10821   
10822   gtk_label_set_text (GTK_LABEL (label), msg);
10823
10824   g_free (msg);
10825
10826   return FALSE;
10827 }
10828
10829 static void
10830 get_ints (GtkWidget *window,
10831           gint      *a,
10832           gint      *b)
10833 {
10834   GtkWidget *spin1;
10835   GtkWidget *spin2;
10836
10837   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
10838   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
10839
10840   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
10841   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
10842 }
10843
10844 static void
10845 set_size_callback (GtkWidget *widget,
10846                    gpointer   data)
10847 {
10848   gint w, h;
10849   
10850   get_ints (data, &w, &h);
10851
10852   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
10853 }
10854
10855 static void
10856 unset_default_size_callback (GtkWidget *widget,
10857                              gpointer   data)
10858 {
10859   gtk_window_set_default_size (g_object_get_data (data, "target"),
10860                                -1, -1);
10861 }
10862
10863 static void
10864 set_default_size_callback (GtkWidget *widget,
10865                            gpointer   data)
10866 {
10867   gint w, h;
10868   
10869   get_ints (data, &w, &h);
10870
10871   gtk_window_set_default_size (g_object_get_data (data, "target"),
10872                                w, h);
10873 }
10874
10875 static void
10876 unset_size_request_callback (GtkWidget *widget,
10877                              gpointer   data)
10878 {
10879   gtk_widget_set_size_request (g_object_get_data (data, "target"),
10880                                -1, -1);
10881 }
10882
10883 static void
10884 set_size_request_callback (GtkWidget *widget,
10885                            gpointer   data)
10886 {
10887   gint w, h;
10888   
10889   get_ints (data, &w, &h);
10890
10891   gtk_widget_set_size_request (g_object_get_data (data, "target"),
10892                                w, h);
10893 }
10894
10895 static void
10896 set_location_callback (GtkWidget *widget,
10897                        gpointer   data)
10898 {
10899   gint x, y;
10900   
10901   get_ints (data, &x, &y);
10902
10903   gtk_window_move (g_object_get_data (data, "target"), x, y);
10904 }
10905
10906 static void
10907 move_to_position_callback (GtkWidget *widget,
10908                            gpointer   data)
10909 {
10910   gint x, y;
10911   GtkWindow *window;
10912
10913   window = g_object_get_data (data, "target");
10914   
10915   gtk_window_get_position (window, &x, &y);
10916
10917   gtk_window_move (window, x, y);
10918 }
10919
10920 static void
10921 set_geometry_callback (GtkWidget *entry,
10922                        gpointer   data)
10923 {
10924   gchar *text;
10925   GtkWindow *target;
10926
10927   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
10928   
10929   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
10930
10931   if (!gtk_window_parse_geometry (target, text))
10932     g_print ("Bad geometry string '%s'\n", text);
10933
10934   g_free (text);
10935 }
10936
10937 static void
10938 allow_shrink_callback (GtkWidget *widget,
10939                        gpointer   data)
10940 {
10941   g_object_set (g_object_get_data (data, "target"),
10942                 "allow_shrink",
10943                 GTK_TOGGLE_BUTTON (widget)->active,
10944                 NULL);
10945 }
10946
10947 static void
10948 allow_grow_callback (GtkWidget *widget,
10949                      gpointer   data)
10950 {
10951   g_object_set (g_object_get_data (data, "target"),
10952                 "allow_grow",
10953                 GTK_TOGGLE_BUTTON (widget)->active,
10954                 NULL);
10955 }
10956
10957 static void
10958 gravity_selected (GtkWidget *widget,
10959                   gpointer   data)
10960 {
10961   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
10962                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
10963 }
10964
10965 static void
10966 pos_selected (GtkWidget *widget,
10967               gpointer   data)
10968 {
10969   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
10970                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
10971 }
10972
10973 static void
10974 move_gravity_window_to_current_position (GtkWidget *widget,
10975                                          gpointer   data)
10976 {
10977   gint x, y;
10978   GtkWindow *window;
10979
10980   window = GTK_WINDOW (data);    
10981   
10982   gtk_window_get_position (window, &x, &y);
10983
10984   gtk_window_move (window, x, y);
10985 }
10986
10987 static void
10988 get_screen_corner (GtkWindow *window,
10989                    gint      *x,
10990                    gint      *y)
10991 {
10992   int w, h;
10993   GdkScreen * screen = gtk_window_get_screen (window);
10994   
10995   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
10996
10997   switch (gtk_window_get_gravity (window))
10998     {
10999     case GDK_GRAVITY_SOUTH_EAST:
11000       *x = gdk_screen_get_width (screen) - w;
11001       *y = gdk_screen_get_height (screen) - h;
11002       break;
11003
11004     case GDK_GRAVITY_NORTH_EAST:
11005       *x = gdk_screen_get_width (screen) - w;
11006       *y = 0;
11007       break;
11008
11009     case GDK_GRAVITY_SOUTH_WEST:
11010       *x = 0;
11011       *y = gdk_screen_get_height (screen) - h;
11012       break;
11013
11014     case GDK_GRAVITY_NORTH_WEST:
11015       *x = 0;
11016       *y = 0;
11017       break;
11018       
11019     case GDK_GRAVITY_SOUTH:
11020       *x = (gdk_screen_get_width (screen) - w) / 2;
11021       *y = gdk_screen_get_height (screen) - h;
11022       break;
11023
11024     case GDK_GRAVITY_NORTH:
11025       *x = (gdk_screen_get_width (screen) - w) / 2;
11026       *y = 0;
11027       break;
11028
11029     case GDK_GRAVITY_WEST:
11030       *x = 0;
11031       *y = (gdk_screen_get_height (screen) - h) / 2;
11032       break;
11033
11034     case GDK_GRAVITY_EAST:
11035       *x = gdk_screen_get_width (screen) - w;
11036       *y = (gdk_screen_get_height (screen) - h) / 2;
11037       break;
11038
11039     case GDK_GRAVITY_CENTER:
11040       *x = (gdk_screen_get_width (screen) - w) / 2;
11041       *y = (gdk_screen_get_height (screen) - h) / 2;
11042       break;
11043
11044     case GDK_GRAVITY_STATIC:
11045       /* pick some random numbers */
11046       *x = 350;
11047       *y = 350;
11048       break;
11049
11050     default:
11051       g_assert_not_reached ();
11052       break;
11053     }
11054 }
11055
11056 static void
11057 move_gravity_window_to_starting_position (GtkWidget *widget,
11058                                           gpointer   data)
11059 {
11060   gint x, y;
11061   GtkWindow *window;
11062
11063   window = GTK_WINDOW (data);    
11064   
11065   get_screen_corner (window,
11066                      &x, &y);
11067   
11068   gtk_window_move (window, x, y);
11069 }
11070
11071 static GtkWidget*
11072 make_gravity_window (GtkWidget   *destroy_with,
11073                      GdkGravity   gravity,
11074                      const gchar *title)
11075 {
11076   GtkWidget *window;
11077   GtkWidget *button;
11078   GtkWidget *vbox;
11079   int x, y;
11080   
11081   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11082
11083   gtk_window_set_screen (GTK_WINDOW (window),
11084                          gtk_widget_get_screen (destroy_with));
11085
11086   vbox = gtk_vbox_new (FALSE, 0);
11087   gtk_widget_show (vbox);
11088   
11089   gtk_container_add (GTK_CONTAINER (window), vbox);
11090   gtk_window_set_title (GTK_WINDOW (window), title);
11091   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
11092
11093   g_signal_connect_object (destroy_with,
11094                            "destroy",
11095                            G_CALLBACK (gtk_widget_destroy),
11096                            window,
11097                            G_CONNECT_SWAPPED);
11098
11099   
11100   button = gtk_button_new_with_mnemonic ("_Move to current position");
11101
11102   g_signal_connect (button, "clicked",
11103                     G_CALLBACK (move_gravity_window_to_current_position),
11104                     window);
11105
11106   gtk_container_add (GTK_CONTAINER (vbox), button);
11107   gtk_widget_show (button);
11108
11109   button = gtk_button_new_with_mnemonic ("Move to _starting position");
11110
11111   g_signal_connect (button, "clicked",
11112                     G_CALLBACK (move_gravity_window_to_starting_position),
11113                     window);
11114
11115   gtk_container_add (GTK_CONTAINER (vbox), button);
11116   gtk_widget_show (button);
11117   
11118   /* Pretend this is the result of --geometry.
11119    * DO NOT COPY THIS CODE unless you are setting --geometry results,
11120    * and in that case you probably should just use gtk_window_parse_geometry().
11121    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
11122    * you are parsing --geometry or equivalent.
11123    */
11124   gtk_window_set_geometry_hints (GTK_WINDOW (window),
11125                                  NULL, NULL,
11126                                  GDK_HINT_USER_POS);
11127
11128   gtk_window_set_default_size (GTK_WINDOW (window),
11129                                200, 200);
11130
11131   get_screen_corner (GTK_WINDOW (window), &x, &y);
11132   
11133   gtk_window_move (GTK_WINDOW (window),
11134                    x, y);
11135   
11136   return window;
11137 }
11138
11139 static void
11140 do_gravity_test (GtkWidget *widget,
11141                  gpointer   data)
11142 {
11143   GtkWidget *destroy_with = data;
11144   GtkWidget *window;
11145   
11146   /* We put a window at each gravity point on the screen. */
11147   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
11148                                 "NorthWest");
11149   gtk_widget_show (window);
11150   
11151   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
11152                                 "SouthEast");
11153   gtk_widget_show (window);
11154
11155   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
11156                                 "NorthEast");
11157   gtk_widget_show (window);
11158
11159   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
11160                                 "SouthWest");
11161   gtk_widget_show (window);
11162
11163   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
11164                                 "South");
11165   gtk_widget_show (window);
11166
11167   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
11168                                 "North");
11169   gtk_widget_show (window);
11170
11171   
11172   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
11173                                 "West");
11174   gtk_widget_show (window);
11175
11176     
11177   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
11178                                 "East");
11179   gtk_widget_show (window);
11180
11181   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
11182                                 "Center");
11183   gtk_widget_show (window);
11184
11185   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
11186                                 "Static");
11187   gtk_widget_show (window);
11188 }
11189
11190 static GtkWidget*
11191 window_controls (GtkWidget *window)
11192 {
11193   GtkWidget *control_window;
11194   GtkWidget *label;
11195   GtkWidget *vbox;
11196   GtkWidget *button;
11197   GtkWidget *spin;
11198   GtkAdjustment *adj;
11199   GtkWidget *entry;
11200   GtkWidget *om;
11201   GtkWidget *menu;
11202   gint i;
11203   
11204   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11205
11206   gtk_window_set_screen (GTK_WINDOW (control_window),
11207                          gtk_widget_get_screen (window));
11208
11209   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
11210   
11211   g_object_set_data (G_OBJECT (control_window),
11212                      "target",
11213                      window);
11214   
11215   g_signal_connect_object (control_window,
11216                            "destroy",
11217                            G_CALLBACK (gtk_widget_destroy),
11218                            window,
11219                            G_CONNECT_SWAPPED);
11220
11221   vbox = gtk_vbox_new (FALSE, 5);
11222   
11223   gtk_container_add (GTK_CONTAINER (control_window), vbox);
11224   
11225   label = gtk_label_new ("<no configure events>");
11226   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11227   
11228   g_signal_connect (window,
11229                     "configure_event",
11230                     G_CALLBACK (configure_event_callback),
11231                     label);
11232
11233   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
11234                                               5.0, 0.0);
11235   spin = gtk_spin_button_new (adj, 0, 0);
11236
11237   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
11238
11239   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
11240
11241   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
11242                                               5.0, 0.0);
11243   spin = gtk_spin_button_new (adj, 0, 0);
11244
11245   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
11246
11247   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
11248
11249   entry = gtk_entry_new ();
11250   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11251
11252   g_signal_connect (entry, "changed",
11253                     G_CALLBACK (set_geometry_callback),
11254                     control_window);
11255
11256   button = gtk_button_new_with_label ("Show gravity test windows");
11257   g_signal_connect_swapped (button,
11258                             "clicked",
11259                             G_CALLBACK (do_gravity_test),
11260                             control_window);
11261   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11262
11263   button = gtk_button_new_with_label ("Reshow with initial size");
11264   g_signal_connect_object (button,
11265                            "clicked",
11266                            G_CALLBACK (gtk_window_reshow_with_initial_size),
11267                            window,
11268                            G_CONNECT_SWAPPED);
11269   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11270   
11271   button = gtk_button_new_with_label ("Queue resize");
11272   g_signal_connect_object (button,
11273                            "clicked",
11274                            G_CALLBACK (gtk_widget_queue_resize),
11275                            window,
11276                            G_CONNECT_SWAPPED);
11277   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11278   
11279   button = gtk_button_new_with_label ("Resize");
11280   g_signal_connect (button,
11281                     "clicked",
11282                     G_CALLBACK (set_size_callback),
11283                     control_window);
11284   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11285
11286   button = gtk_button_new_with_label ("Set default size");
11287   g_signal_connect (button,
11288                     "clicked",
11289                     G_CALLBACK (set_default_size_callback),
11290                     control_window);
11291   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11292
11293   button = gtk_button_new_with_label ("Unset default size");
11294   g_signal_connect (button,
11295                     "clicked",
11296                     G_CALLBACK (unset_default_size_callback),
11297                     control_window);
11298   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11299   
11300   button = gtk_button_new_with_label ("Set size request");
11301   g_signal_connect (button,
11302                     "clicked",
11303                     G_CALLBACK (set_size_request_callback),
11304                     control_window);
11305   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11306
11307   button = gtk_button_new_with_label ("Unset size request");
11308   g_signal_connect (button,
11309                     "clicked",
11310                     G_CALLBACK (unset_size_request_callback),
11311                     control_window);
11312   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11313   
11314   button = gtk_button_new_with_label ("Move");
11315   g_signal_connect (button,
11316                     "clicked",
11317                     G_CALLBACK (set_location_callback),
11318                     control_window);
11319   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11320
11321   button = gtk_button_new_with_label ("Move to current position");
11322   g_signal_connect (button,
11323                     "clicked",
11324                     G_CALLBACK (move_to_position_callback),
11325                     control_window);
11326   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11327   
11328   button = gtk_check_button_new_with_label ("Allow shrink");
11329   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
11330   g_signal_connect (button,
11331                     "toggled",
11332                     G_CALLBACK (allow_shrink_callback),
11333                     control_window);
11334   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11335
11336   button = gtk_check_button_new_with_label ("Allow grow");
11337   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
11338   g_signal_connect (button,
11339                     "toggled",
11340                     G_CALLBACK (allow_grow_callback),
11341                     control_window);
11342   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11343   
11344   button = gtk_button_new_with_mnemonic ("_Show");
11345   g_signal_connect_object (button,
11346                            "clicked",
11347                            G_CALLBACK (gtk_widget_show),
11348                            window,
11349                            G_CONNECT_SWAPPED);
11350   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11351
11352   button = gtk_button_new_with_mnemonic ("_Hide");
11353   g_signal_connect_object (button,
11354                            "clicked",
11355                            G_CALLBACK (gtk_widget_hide),
11356                            window,
11357                            G_CONNECT_SWAPPED);
11358   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11359   
11360   menu = gtk_menu_new ();
11361   
11362   i = 0;
11363   while (i < 10)
11364     {
11365       GtkWidget *mi;
11366       static gchar *names[] = {
11367         "GDK_GRAVITY_NORTH_WEST",
11368         "GDK_GRAVITY_NORTH",
11369         "GDK_GRAVITY_NORTH_EAST",
11370         "GDK_GRAVITY_WEST",
11371         "GDK_GRAVITY_CENTER",
11372         "GDK_GRAVITY_EAST",
11373         "GDK_GRAVITY_SOUTH_WEST",
11374         "GDK_GRAVITY_SOUTH",
11375         "GDK_GRAVITY_SOUTH_EAST",
11376         "GDK_GRAVITY_STATIC",
11377         NULL
11378       };
11379
11380       g_assert (names[i]);
11381       
11382       mi = gtk_menu_item_new_with_label (names[i]);
11383
11384       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
11385
11386       ++i;
11387     }
11388   
11389   gtk_widget_show_all (menu);
11390   
11391   om = gtk_option_menu_new ();
11392   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
11393   
11394
11395   g_signal_connect (om,
11396                     "changed",
11397                     G_CALLBACK (gravity_selected),
11398                     control_window);
11399
11400   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
11401
11402
11403   menu = gtk_menu_new ();
11404   
11405   i = 0;
11406   while (i < 5)
11407     {
11408       GtkWidget *mi;
11409       static gchar *names[] = {
11410         "GTK_WIN_POS_NONE",
11411         "GTK_WIN_POS_CENTER",
11412         "GTK_WIN_POS_MOUSE",
11413         "GTK_WIN_POS_CENTER_ALWAYS",
11414         "GTK_WIN_POS_CENTER_ON_PARENT",
11415         NULL
11416       };
11417
11418       g_assert (names[i]);
11419       
11420       mi = gtk_menu_item_new_with_label (names[i]);
11421
11422       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
11423
11424       ++i;
11425     }
11426   
11427   gtk_widget_show_all (menu);
11428   
11429   om = gtk_option_menu_new ();
11430   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
11431   
11432
11433   g_signal_connect (om,
11434                     "changed",
11435                     G_CALLBACK (pos_selected),
11436                     control_window);
11437
11438   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
11439   
11440   gtk_widget_show_all (vbox);
11441   
11442   return control_window;
11443 }
11444
11445 void
11446 create_window_sizing (GtkWidget *widget)
11447 {
11448   static GtkWidget *window = NULL;
11449   static GtkWidget *target_window = NULL;
11450
11451   if (!target_window)
11452     {
11453       GtkWidget *label;
11454       
11455       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11456       gtk_window_set_screen (GTK_WINDOW (target_window),
11457                              gtk_widget_get_screen (widget));
11458       label = gtk_label_new (NULL);
11459       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");
11460       gtk_container_add (GTK_CONTAINER (target_window), label);
11461       gtk_widget_show (label);
11462       
11463       g_signal_connect (target_window, "destroy",
11464                         G_CALLBACK (gtk_widget_destroyed),
11465                         &target_window);
11466
11467       window = window_controls (target_window);
11468       
11469       g_signal_connect (window, "destroy",
11470                         G_CALLBACK (gtk_widget_destroyed),
11471                         &window);
11472       
11473       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
11474     }
11475
11476   /* don't show target window by default, we want to allow testing
11477    * of behavior on first show.
11478    */
11479   
11480   if (!GTK_WIDGET_VISIBLE (window))
11481     gtk_widget_show (window);
11482   else
11483     gtk_widget_destroy (window);
11484 }
11485
11486 /*
11487  * GtkProgressBar
11488  */
11489
11490 typedef struct _ProgressData {
11491   GtkWidget *window;
11492   GtkWidget *pbar;
11493   GtkWidget *block_spin;
11494   GtkWidget *x_align_spin;
11495   GtkWidget *y_align_spin;
11496   GtkWidget *step_spin;
11497   GtkWidget *act_blocks_spin;
11498   GtkWidget *label;
11499   GtkWidget *omenu1;
11500   GtkWidget *elmenu;
11501   GtkWidget *omenu2;
11502   GtkWidget *entry;
11503   int timer;
11504 } ProgressData;
11505
11506 gint
11507 progress_timeout (gpointer data)
11508 {
11509   gdouble new_val;
11510   GtkAdjustment *adj;
11511
11512   adj = GTK_PROGRESS (data)->adjustment;
11513
11514   new_val = adj->value + 1;
11515   if (new_val > adj->upper)
11516     new_val = adj->lower;
11517
11518   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
11519
11520   return TRUE;
11521 }
11522
11523 static void
11524 destroy_progress (GtkWidget     *widget,
11525                   ProgressData **pdata)
11526 {
11527   gtk_timeout_remove ((*pdata)->timer);
11528   (*pdata)->timer = 0;
11529   (*pdata)->window = NULL;
11530   g_free (*pdata);
11531   *pdata = NULL;
11532 }
11533
11534 static void
11535 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
11536 {
11537   ProgressData *pdata;
11538   gint i;
11539
11540   pdata = (ProgressData *) data;
11541
11542   if (!GTK_WIDGET_MAPPED (widget))
11543     return;
11544
11545   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
11546
11547   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
11548                                     (GtkProgressBarOrientation) i);
11549 }
11550
11551 static void
11552 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
11553 {
11554   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
11555                               GTK_TOGGLE_BUTTON (widget)->active);
11556   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
11557   gtk_widget_set_sensitive (pdata->x_align_spin,
11558                             GTK_TOGGLE_BUTTON (widget)->active);
11559   gtk_widget_set_sensitive (pdata->y_align_spin,
11560                             GTK_TOGGLE_BUTTON (widget)->active);
11561 }
11562
11563 static void
11564 progressbar_toggle_ellipsize (GtkWidget *widget,
11565                               gpointer   data)
11566 {
11567   ProgressData *pdata = data;
11568   if (GTK_WIDGET_DRAWABLE (widget))
11569     {
11570       gint i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
11571       gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
11572     }
11573 }
11574
11575 static void
11576 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
11577 {
11578   ProgressData *pdata;
11579   gint i;
11580
11581   pdata = (ProgressData *) data;
11582
11583   if (!GTK_WIDGET_MAPPED (widget))
11584     return;
11585
11586   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
11587
11588   if (i == 1)
11589     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
11590   else
11591     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
11592   
11593   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
11594                                   (GtkProgressBarStyle) i);
11595 }
11596
11597 static void
11598 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
11599 {
11600   char buf[20];
11601
11602   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
11603     sprintf (buf, "???");
11604   else
11605     sprintf (buf, "%.0f%%", 100 *
11606              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
11607   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
11608 }
11609
11610 static void
11611 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
11612 {
11613   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
11614   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
11615      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
11616 }
11617
11618 static void
11619 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
11620 {
11621   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
11622      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
11623 }
11624
11625 static void
11626 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
11627 {
11628   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
11629                gtk_spin_button_get_value_as_int 
11630                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
11631 }
11632
11633 static void
11634 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
11635 {
11636   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
11637          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->x_align_spin)),
11638          gtk_spin_button_get_value (GTK_SPIN_BUTTON (pdata->y_align_spin)));
11639 }
11640
11641 static void
11642 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
11643 {
11644   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
11645                                   GTK_TOGGLE_BUTTON (widget)->active);
11646   gtk_widget_set_sensitive (pdata->step_spin, 
11647                             GTK_TOGGLE_BUTTON (widget)->active);
11648   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
11649                             GTK_TOGGLE_BUTTON (widget)->active);
11650 }
11651
11652 static void
11653 entry_changed (GtkWidget *widget, ProgressData *pdata)
11654 {
11655   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
11656                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
11657 }
11658
11659 void
11660 create_progress_bar (GtkWidget *widget)
11661 {
11662   GtkWidget *button;
11663   GtkWidget *vbox;
11664   GtkWidget *vbox2;
11665   GtkWidget *hbox;
11666   GtkWidget *check;
11667   GtkWidget *frame;
11668   GtkWidget *tab;
11669   GtkWidget *label;
11670   GtkWidget *align;
11671   GtkAdjustment *adj;
11672   static ProgressData *pdata = NULL;
11673
11674   static gchar *items1[] =
11675   {
11676     "Left-Right",
11677     "Right-Left",
11678     "Bottom-Top",
11679     "Top-Bottom"
11680   };
11681
11682   static gchar *items2[] =
11683   {
11684     "Continuous",
11685     "Discrete"
11686   };
11687
11688   static char *ellipsize_items[] = {
11689     "None",     // PANGO_ELLIPSIZE_NONE,
11690     "Start",    // PANGO_ELLIPSIZE_START,
11691     "Middle",   // PANGO_ELLIPSIZE_MIDDLE,
11692     "End",      // PANGO_ELLIPSIZE_END
11693   };
11694   
11695   if (!pdata)
11696     pdata = g_new0 (ProgressData, 1);
11697
11698   if (!pdata->window)
11699     {
11700       pdata->window = gtk_dialog_new ();
11701
11702       gtk_window_set_screen (GTK_WINDOW (pdata->window),
11703                              gtk_widget_get_screen (widget));
11704
11705       gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
11706
11707       g_signal_connect (pdata->window, "destroy",
11708                         G_CALLBACK (destroy_progress),
11709                         &pdata);
11710
11711       pdata->timer = 0;
11712
11713       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
11714       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
11715
11716       vbox = gtk_vbox_new (FALSE, 5);
11717       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11718       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
11719                           vbox, FALSE, TRUE, 0);
11720
11721       frame = gtk_frame_new ("Progress");
11722       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
11723
11724       vbox2 = gtk_vbox_new (FALSE, 5);
11725       gtk_container_add (GTK_CONTAINER (frame), vbox2);
11726
11727       align = gtk_alignment_new (0.5, 0.5, 0, 0);
11728       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
11729
11730       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
11731       g_signal_connect (adj, "value_changed",
11732                         G_CALLBACK (progress_value_changed), pdata);
11733
11734       pdata->pbar = gtk_widget_new (GTK_TYPE_PROGRESS_BAR,
11735                                     "adjustment", adj,
11736                                     "ellipsize", PANGO_ELLIPSIZE_MIDDLE,
11737                                     NULL);
11738       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
11739                                       "%v from [%l,%u] (=%p%%)");
11740       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
11741       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
11742
11743       align = gtk_alignment_new (0.5, 0.5, 0, 0);
11744       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
11745
11746       hbox = gtk_hbox_new (FALSE, 5);
11747       gtk_container_add (GTK_CONTAINER (align), hbox);
11748       label = gtk_label_new ("Label updated by user :"); 
11749       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
11750       pdata->label = gtk_label_new ("");
11751       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
11752
11753       frame = gtk_frame_new ("Options");
11754       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
11755
11756       vbox2 = gtk_vbox_new (FALSE, 5);
11757       gtk_container_add (GTK_CONTAINER (frame), vbox2);
11758
11759       tab = gtk_table_new (7, 2, FALSE);
11760       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
11761
11762       label = gtk_label_new ("Orientation :");
11763       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
11764                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11765                         5, 5);
11766       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
11767
11768       pdata->omenu1 = build_option_menu (items1, 4, 0,
11769                                          progressbar_toggle_orientation,
11770                                          pdata);
11771       hbox = gtk_hbox_new (FALSE, 0);
11772       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
11773                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11774                         5, 5);
11775       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
11776       
11777       check = gtk_check_button_new_with_label ("Show text");
11778       g_signal_connect (check, "clicked",
11779                         G_CALLBACK (toggle_show_text),
11780                         pdata);
11781       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
11782                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11783                         5, 5);
11784
11785       hbox = gtk_hbox_new (FALSE, 0);
11786       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
11787                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11788                         5, 5);
11789
11790       label = gtk_label_new ("Format : ");
11791       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
11792
11793       pdata->entry = gtk_entry_new ();
11794       g_signal_connect (pdata->entry, "changed",
11795                         G_CALLBACK (entry_changed),
11796                         pdata);
11797       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
11798       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
11799       gtk_widget_set_size_request (pdata->entry, 100, -1);
11800       gtk_widget_set_sensitive (pdata->entry, FALSE);
11801
11802       label = gtk_label_new ("Text align :");
11803       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
11804                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11805                         5, 5);
11806       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
11807
11808       hbox = gtk_hbox_new (FALSE, 0);
11809       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
11810                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11811                         5, 5);
11812
11813       label = gtk_label_new ("x :");
11814       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
11815       
11816       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
11817       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
11818       g_signal_connect (adj, "value_changed",
11819                         G_CALLBACK (adjust_align), pdata);
11820       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
11821       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
11822
11823       label = gtk_label_new ("y :");
11824       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
11825
11826       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
11827       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
11828       g_signal_connect (adj, "value_changed",
11829                         G_CALLBACK (adjust_align), pdata);
11830       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
11831       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
11832
11833       label = gtk_label_new ("Ellipsize text :");
11834       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 10, 11,
11835                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11836                         5, 5);
11837       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
11838       pdata->elmenu = build_option_menu (ellipsize_items,
11839                                          sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
11840                                          2, // PANGO_ELLIPSIZE_MIDDLE
11841                                          progressbar_toggle_ellipsize,
11842                                          pdata);
11843       hbox = gtk_hbox_new (FALSE, 0);
11844       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 10, 11,
11845                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11846                         5, 5);
11847       gtk_box_pack_start (GTK_BOX (hbox), pdata->elmenu, TRUE, TRUE, 0);
11848
11849       label = gtk_label_new ("Bar Style :");
11850       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 13, 14,
11851                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11852                         5, 5);
11853       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
11854
11855       pdata->omenu2 = build_option_menu (items2, 2, 0,
11856                                          progressbar_toggle_bar_style,
11857                                          pdata);
11858       hbox = gtk_hbox_new (FALSE, 0);
11859       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 13, 14,
11860                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11861                         5, 5);
11862       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
11863
11864       label = gtk_label_new ("Block count :");
11865       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 14, 15,
11866                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11867                         5, 5);
11868       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
11869
11870       hbox = gtk_hbox_new (FALSE, 0);
11871       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 14, 15,
11872                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11873                         5, 5);
11874       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
11875       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
11876       g_signal_connect (adj, "value_changed",
11877                         G_CALLBACK (adjust_blocks), pdata);
11878       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
11879       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
11880
11881       check = gtk_check_button_new_with_label ("Activity mode");
11882       g_signal_connect (check, "clicked",
11883                         G_CALLBACK (toggle_activity_mode), pdata);
11884       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 15, 16,
11885                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11886                         5, 5);
11887
11888       hbox = gtk_hbox_new (FALSE, 0);
11889       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 15, 16,
11890                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11891                         5, 5);
11892       label = gtk_label_new ("Step size : ");
11893       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
11894       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
11895       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
11896       g_signal_connect (adj, "value_changed",
11897                         G_CALLBACK (adjust_step), pdata);
11898       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
11899       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
11900
11901       hbox = gtk_hbox_new (FALSE, 0);
11902       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 16, 17,
11903                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
11904                         5, 5);
11905       label = gtk_label_new ("Blocks :     ");
11906       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
11907       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
11908       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
11909       g_signal_connect (adj, "value_changed",
11910                         G_CALLBACK (adjust_act_blocks), pdata);
11911       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
11912                           0);
11913       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
11914
11915       button = gtk_button_new_with_label ("close");
11916       g_signal_connect_swapped (button, "clicked",
11917                                 G_CALLBACK (gtk_widget_destroy),
11918                                 pdata->window);
11919       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11920       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
11921                           button, TRUE, TRUE, 0);
11922       gtk_widget_grab_default (button);
11923     }
11924
11925   if (!GTK_WIDGET_VISIBLE (pdata->window))
11926     gtk_widget_show_all (pdata->window);
11927   else
11928     gtk_widget_destroy (pdata->window);
11929 }
11930
11931 /*
11932  * Properties
11933  */
11934
11935 typedef struct {
11936   int x;
11937   int y;
11938   gboolean found;
11939   gboolean first;
11940   GtkWidget *res_widget;
11941 } FindWidgetData;
11942
11943 static void
11944 find_widget (GtkWidget *widget, FindWidgetData *data)
11945 {
11946   GtkAllocation new_allocation;
11947   gint x_offset = 0;
11948   gint y_offset = 0;
11949
11950   new_allocation = widget->allocation;
11951
11952   if (data->found || !GTK_WIDGET_MAPPED (widget))
11953     return;
11954
11955   /* Note that in the following code, we only count the
11956    * position as being inside a WINDOW widget if it is inside
11957    * widget->window; points that are outside of widget->window
11958    * but within the allocation are not counted. This is consistent
11959    * with the way we highlight drag targets.
11960    */
11961   if (!GTK_WIDGET_NO_WINDOW (widget))
11962     {
11963       new_allocation.x = 0;
11964       new_allocation.y = 0;
11965     }
11966   
11967   if (widget->parent && !data->first)
11968     {
11969       GdkWindow *window = widget->window;
11970       while (window != widget->parent->window)
11971         {
11972           gint tx, ty, twidth, theight;
11973           gdk_drawable_get_size (window, &twidth, &theight);
11974
11975           if (new_allocation.x < 0)
11976             {
11977               new_allocation.width += new_allocation.x;
11978               new_allocation.x = 0;
11979             }
11980           if (new_allocation.y < 0)
11981             {
11982               new_allocation.height += new_allocation.y;
11983               new_allocation.y = 0;
11984             }
11985           if (new_allocation.x + new_allocation.width > twidth)
11986             new_allocation.width = twidth - new_allocation.x;
11987           if (new_allocation.y + new_allocation.height > theight)
11988             new_allocation.height = theight - new_allocation.y;
11989
11990           gdk_window_get_position (window, &tx, &ty);
11991           new_allocation.x += tx;
11992           x_offset += tx;
11993           new_allocation.y += ty;
11994           y_offset += ty;
11995           
11996           window = gdk_window_get_parent (window);
11997         }
11998     }
11999
12000   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
12001       (data->x < new_allocation.x + new_allocation.width) && 
12002       (data->y < new_allocation.y + new_allocation.height))
12003     {
12004       /* First, check if the drag is in a valid drop site in
12005        * one of our children 
12006        */
12007       if (GTK_IS_CONTAINER (widget))
12008         {
12009           FindWidgetData new_data = *data;
12010           
12011           new_data.x -= x_offset;
12012           new_data.y -= y_offset;
12013           new_data.found = FALSE;
12014           new_data.first = FALSE;
12015           
12016           gtk_container_forall (GTK_CONTAINER (widget),
12017                                 (GtkCallback)find_widget,
12018                                 &new_data);
12019           
12020           data->found = new_data.found;
12021           if (data->found)
12022             data->res_widget = new_data.res_widget;
12023         }
12024
12025       /* If not, and this widget is registered as a drop site, check to
12026        * emit "drag_motion" to check if we are actually in
12027        * a drop site.
12028        */
12029       if (!data->found)
12030         {
12031           data->found = TRUE;
12032           data->res_widget = widget;
12033         }
12034     }
12035 }
12036
12037 static GtkWidget *
12038 find_widget_at_pointer (GdkDisplay *display)
12039 {
12040   GtkWidget *widget = NULL;
12041   GdkWindow *pointer_window;
12042   gint x, y;
12043   FindWidgetData data;
12044  
12045  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
12046  
12047  if (pointer_window)
12048    gdk_window_get_user_data (pointer_window, (gpointer) &widget);
12049
12050  if (widget)
12051    {
12052      gdk_window_get_pointer (widget->window,
12053                              &x, &y, NULL);
12054      
12055      data.x = x;
12056      data.y = y;
12057      data.found = FALSE;
12058      data.first = TRUE;
12059
12060      find_widget (widget, &data);
12061      if (data.found)
12062        return data.res_widget;
12063      return widget;
12064    }
12065  return NULL;
12066 }
12067
12068 struct PropertiesData {
12069   GtkWidget **window;
12070   GdkCursor *cursor;
12071   gboolean in_query;
12072   gint handler;
12073 };
12074
12075 static void
12076 destroy_properties (GtkWidget             *widget,
12077                     struct PropertiesData *data)
12078 {
12079   if (data->window)
12080     {
12081       *data->window = NULL;
12082       data->window = NULL;
12083     }
12084
12085   if (data->cursor)
12086     {
12087       gdk_cursor_unref (data->cursor);
12088       data->cursor = NULL;
12089     }
12090
12091   if (data->handler)
12092     {
12093       g_signal_handler_disconnect (widget, data->handler);
12094       data->handler = 0;
12095     }
12096
12097   g_free (data);
12098 }
12099
12100 static gint
12101 property_query_event (GtkWidget        *widget,
12102                       GdkEvent         *event,
12103                       struct PropertiesData *data)
12104 {
12105   GtkWidget *res_widget = NULL;
12106
12107   if (!data->in_query)
12108     return FALSE;
12109   
12110   if (event->type == GDK_BUTTON_RELEASE)
12111     {
12112       gtk_grab_remove (widget);
12113       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
12114                                   GDK_CURRENT_TIME);
12115       
12116       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
12117       if (res_widget)
12118         {
12119           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
12120                              gtk_widget_get_screen (widget));
12121           create_prop_editor (G_OBJECT (res_widget), 0);
12122         }
12123
12124       data->in_query = FALSE;
12125     }
12126   return FALSE;
12127 }
12128
12129
12130 static void
12131 query_properties (GtkButton *button,
12132                   struct PropertiesData *data)
12133 {
12134   gint failure;
12135
12136   g_signal_connect (button, "event",
12137                     G_CALLBACK (property_query_event), data);
12138
12139
12140   if (!data->cursor)
12141     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (button)),
12142                                                GDK_TARGET);
12143   
12144   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
12145                               TRUE,
12146                               GDK_BUTTON_RELEASE_MASK,
12147                               NULL,
12148                               data->cursor,
12149                               GDK_CURRENT_TIME);
12150
12151   gtk_grab_add (GTK_WIDGET (button));
12152
12153   data->in_query = TRUE;
12154 }
12155
12156 static void
12157 create_properties (GtkWidget *widget)
12158 {
12159   static GtkWidget *window = NULL;
12160   GtkWidget *button;
12161   GtkWidget *vbox;
12162   GtkWidget *label;
12163   struct PropertiesData *data;
12164
12165   data = g_new (struct PropertiesData, 1);
12166   data->window = &window;
12167   data->in_query = FALSE;
12168   data->cursor = NULL;
12169   data->handler = 0;
12170
12171   if (!window)
12172     {
12173       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12174
12175       gtk_window_set_screen (GTK_WINDOW (window),
12176                              gtk_widget_get_screen (widget));      
12177
12178       data->handler = g_signal_connect (window, "destroy",
12179                                         G_CALLBACK (destroy_properties),
12180                                         data);
12181
12182       gtk_window_set_title (GTK_WINDOW (window), "test properties");
12183       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
12184
12185       vbox = gtk_vbox_new (FALSE, 1);
12186       gtk_container_add (GTK_CONTAINER (window), vbox);
12187             
12188       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
12189       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
12190       
12191       button = gtk_button_new_with_label ("Query properties");
12192       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
12193       g_signal_connect (button, "clicked",
12194                         G_CALLBACK (query_properties),
12195                         data);
12196     }
12197
12198   if (!GTK_WIDGET_VISIBLE (window))
12199     gtk_widget_show_all (window);
12200   else
12201     gtk_widget_destroy (window);
12202   
12203 }
12204
12205
12206 /*
12207  * Color Preview
12208  */
12209
12210 static int color_idle = 0;
12211
12212 gint
12213 color_idle_func (GtkWidget *preview)
12214 {
12215   static int count = 1;
12216   guchar buf[768];
12217   int i, j, k;
12218
12219   for (i = 0; i < 256; i++)
12220     {
12221       for (j = 0, k = 0; j < 256; j++)
12222         {
12223           buf[k+0] = i + count;
12224           buf[k+1] = 0;
12225           buf[k+2] = j + count;
12226           k += 3;
12227         }
12228
12229       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
12230     }
12231
12232   count += 1;
12233
12234   gtk_widget_queue_draw (preview);
12235   gdk_window_process_updates (preview->window, TRUE);
12236
12237   return TRUE;
12238 }
12239
12240 static void
12241 color_preview_destroy (GtkWidget  *widget,
12242                        GtkWidget **window)
12243 {
12244   gtk_idle_remove (color_idle);
12245   color_idle = 0;
12246
12247   *window = NULL;
12248 }
12249
12250 void
12251 create_color_preview (GtkWidget *widget)
12252 {
12253   static GtkWidget *window = NULL;
12254   GtkWidget *preview;
12255   guchar buf[768];
12256   int i, j, k;
12257
12258   if (!window)
12259     {
12260       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12261       
12262       gtk_window_set_screen (GTK_WINDOW (window),
12263                              gtk_widget_get_screen (widget));
12264
12265       g_signal_connect (window, "destroy",
12266                         G_CALLBACK (color_preview_destroy),
12267                         &window);
12268
12269       gtk_window_set_title (GTK_WINDOW (window), "test");
12270       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
12271
12272       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
12273       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
12274       gtk_container_add (GTK_CONTAINER (window), preview);
12275
12276       for (i = 0; i < 256; i++)
12277         {
12278           for (j = 0, k = 0; j < 256; j++)
12279             {
12280               buf[k+0] = i;
12281               buf[k+1] = 0;
12282               buf[k+2] = j;
12283               k += 3;
12284             }
12285
12286           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
12287         }
12288
12289       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
12290     }
12291
12292   if (!GTK_WIDGET_VISIBLE (window))
12293     gtk_widget_show_all (window);
12294   else
12295     gtk_widget_destroy (window);
12296 }
12297
12298 /*
12299  * Gray Preview
12300  */
12301
12302 static int gray_idle = 0;
12303
12304 gint
12305 gray_idle_func (GtkWidget *preview)
12306 {
12307   static int count = 1;
12308   guchar buf[256];
12309   int i, j;
12310
12311   for (i = 0; i < 256; i++)
12312     {
12313       for (j = 0; j < 256; j++)
12314         buf[j] = i + j + count;
12315
12316       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
12317     }
12318
12319   count += 1;
12320
12321   gtk_widget_draw (preview, NULL);
12322
12323   return TRUE;
12324 }
12325
12326 static void
12327 gray_preview_destroy (GtkWidget  *widget,
12328                       GtkWidget **window)
12329 {
12330   gtk_idle_remove (gray_idle);
12331   gray_idle = 0;
12332
12333   *window = NULL;
12334 }
12335
12336 void
12337 create_gray_preview (GtkWidget *widget)
12338 {
12339   static GtkWidget *window = NULL;
12340   GtkWidget *preview;
12341   guchar buf[256];
12342   int i, j;
12343
12344   if (!window)
12345     {
12346       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12347
12348       gtk_window_set_screen (GTK_WINDOW (window),
12349                              gtk_widget_get_screen (widget));
12350
12351       g_signal_connect (window, "destroy",
12352                         G_CALLBACK (gray_preview_destroy),
12353                         &window);
12354
12355       gtk_window_set_title (GTK_WINDOW (window), "test");
12356       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
12357
12358       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
12359       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
12360       gtk_container_add (GTK_CONTAINER (window), preview);
12361
12362       for (i = 0; i < 256; i++)
12363         {
12364           for (j = 0; j < 256; j++)
12365             buf[j] = i + j;
12366
12367           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
12368         }
12369
12370       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
12371     }
12372
12373   if (!GTK_WIDGET_VISIBLE (window))
12374     gtk_widget_show_all (window);
12375   else
12376     gtk_widget_destroy (window);
12377 }
12378
12379
12380 /*
12381  * Selection Test
12382  */
12383
12384 void
12385 selection_test_received (GtkWidget *list, GtkSelectionData *data)
12386 {
12387   GdkAtom *atoms;
12388   GtkWidget *list_item;
12389   GList *item_list;
12390   int i, l;
12391
12392   if (data->length < 0)
12393     {
12394       g_print ("Selection retrieval failed\n");
12395       return;
12396     }
12397   if (data->type != GDK_SELECTION_TYPE_ATOM)
12398     {
12399       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
12400       return;
12401     }
12402
12403   /* Clear out any current list items */
12404
12405   gtk_list_clear_items (GTK_LIST(list), 0, -1);
12406
12407   /* Add new items to list */
12408
12409   atoms = (GdkAtom *)data->data;
12410
12411   item_list = NULL;
12412   l = data->length / sizeof (GdkAtom);
12413   for (i = 0; i < l; i++)
12414     {
12415       char *name;
12416       name = gdk_atom_name (atoms[i]);
12417       if (name != NULL)
12418         {
12419           list_item = gtk_list_item_new_with_label (name);
12420           g_free (name);
12421         }
12422       else
12423         list_item = gtk_list_item_new_with_label ("(bad atom)");
12424
12425       gtk_widget_show (list_item);
12426       item_list = g_list_append (item_list, list_item);
12427     }
12428
12429   gtk_list_append_items (GTK_LIST (list), item_list);
12430
12431   return;
12432 }
12433
12434 void
12435 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
12436 {
12437   static GdkAtom targets_atom = GDK_NONE;
12438
12439   if (targets_atom == GDK_NONE)
12440     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
12441
12442   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
12443                          GDK_CURRENT_TIME);
12444 }
12445
12446 void
12447 create_selection_test (GtkWidget *widget)
12448 {
12449   static GtkWidget *window = NULL;
12450   GtkWidget *button;
12451   GtkWidget *vbox;
12452   GtkWidget *scrolled_win;
12453   GtkWidget *list;
12454   GtkWidget *label;
12455
12456   if (!window)
12457     {
12458       window = gtk_dialog_new ();
12459       
12460       gtk_window_set_screen (GTK_WINDOW (window),
12461                              gtk_widget_get_screen (widget));
12462
12463       g_signal_connect (window, "destroy",
12464                         G_CALLBACK (gtk_widget_destroyed),
12465                         &window);
12466
12467       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
12468       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
12469
12470       /* Create the list */
12471
12472       vbox = gtk_vbox_new (FALSE, 5);
12473       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
12474       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
12475                           TRUE, TRUE, 0);
12476
12477       label = gtk_label_new ("Gets available targets for current selection");
12478       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
12479
12480       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
12481       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
12482                                       GTK_POLICY_AUTOMATIC, 
12483                                       GTK_POLICY_AUTOMATIC);
12484       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
12485       gtk_widget_set_size_request (scrolled_win, 100, 200);
12486
12487       list = gtk_list_new ();
12488       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
12489
12490       g_signal_connect (list, "selection_received",
12491                         G_CALLBACK (selection_test_received), NULL);
12492
12493       /* .. And create some buttons */
12494       button = gtk_button_new_with_label ("Get Targets");
12495       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
12496                           button, TRUE, TRUE, 0);
12497
12498       g_signal_connect (button, "clicked",
12499                         G_CALLBACK (selection_test_get_targets), list);
12500
12501       button = gtk_button_new_with_label ("Quit");
12502       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
12503                           button, TRUE, TRUE, 0);
12504
12505       g_signal_connect_swapped (button, "clicked",
12506                                 G_CALLBACK (gtk_widget_destroy),
12507                                 window);
12508     }
12509
12510   if (!GTK_WIDGET_VISIBLE (window))
12511     gtk_widget_show_all (window);
12512   else
12513     gtk_widget_destroy (window);
12514 }
12515
12516 /*
12517  * Gamma Curve
12518  */
12519
12520 void
12521 create_gamma_curve (GtkWidget *widget)
12522 {
12523   static GtkWidget *window = NULL, *curve;
12524   static int count = 0;
12525   gfloat vec[256];
12526   gint max;
12527   gint i;
12528   
12529   if (!window)
12530     {
12531       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12532       gtk_window_set_screen (GTK_WINDOW (window),
12533                              gtk_widget_get_screen (widget));
12534
12535       gtk_window_set_title (GTK_WINDOW (window), "test");
12536       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
12537
12538       g_signal_connect (window, "destroy",
12539                         G_CALLBACK(gtk_widget_destroyed),
12540                         &window);
12541
12542       curve = gtk_gamma_curve_new ();
12543       gtk_container_add (GTK_CONTAINER (window), curve);
12544       gtk_widget_show (curve);
12545     }
12546
12547   max = 127 + (count % 2)*128;
12548   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
12549                        0, max, 0, max);
12550   for (i = 0; i < max; ++i)
12551     vec[i] = (127 / sqrt (max)) * sqrt (i);
12552   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
12553                         max, vec);
12554
12555   if (!GTK_WIDGET_VISIBLE (window))
12556     gtk_widget_show (window);
12557   else if (count % 4 == 3)
12558     {
12559       gtk_widget_destroy (window);
12560       window = NULL;
12561     }
12562
12563   ++count;
12564 }
12565
12566 /*
12567  * Test scrolling
12568  */
12569
12570 static int scroll_test_pos = 0.0;
12571
12572 static gint
12573 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
12574                     GtkAdjustment *adj)
12575 {
12576   gint i,j;
12577   gint imin, imax, jmin, jmax;
12578   
12579   imin = (event->area.x) / 10;
12580   imax = (event->area.x + event->area.width + 9) / 10;
12581
12582   jmin = ((int)adj->value + event->area.y) / 10;
12583   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
12584
12585   gdk_window_clear_area (widget->window,
12586                          event->area.x, event->area.y,
12587                          event->area.width, event->area.height);
12588
12589   for (i=imin; i<imax; i++)
12590     for (j=jmin; j<jmax; j++)
12591       if ((i+j) % 2)
12592         gdk_draw_rectangle (widget->window, 
12593                             widget->style->black_gc,
12594                             TRUE,
12595                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
12596
12597   return TRUE;
12598 }
12599
12600 static gint
12601 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
12602                     GtkAdjustment *adj)
12603 {
12604   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
12605                                     -adj->page_increment / 2:
12606                                     adj->page_increment / 2);
12607   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
12608   gtk_adjustment_set_value (adj, new_value);  
12609   
12610   return TRUE;
12611 }
12612
12613 static void
12614 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
12615                        GtkAdjustment *adj)
12616 {
12617   adj->page_increment = 0.9 * widget->allocation.height;
12618   adj->page_size = widget->allocation.height;
12619
12620   g_signal_emit_by_name (adj, "changed");
12621 }
12622
12623 static void
12624 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
12625 {
12626   /* gint source_min = (int)adj->value - scroll_test_pos; */
12627   gint dy;
12628
12629   dy = scroll_test_pos - (int)adj->value;
12630   scroll_test_pos = adj->value;
12631
12632   if (!GTK_WIDGET_DRAWABLE (widget))
12633     return;
12634   gdk_window_scroll (widget->window, 0, dy);
12635   gdk_window_process_updates (widget->window, FALSE);
12636 }
12637
12638
12639 void
12640 create_scroll_test (GtkWidget *widget)
12641 {
12642   static GtkWidget *window = NULL;
12643   GtkWidget *hbox;
12644   GtkWidget *drawing_area;
12645   GtkWidget *scrollbar;
12646   GtkWidget *button;
12647   GtkAdjustment *adj;
12648   GdkGeometry geometry;
12649   GdkWindowHints geometry_mask;
12650
12651   if (!window)
12652     {
12653       window = gtk_dialog_new ();
12654
12655       gtk_window_set_screen (GTK_WINDOW (window),
12656                              gtk_widget_get_screen (widget));
12657
12658       g_signal_connect (window, "destroy",
12659                         G_CALLBACK (gtk_widget_destroyed),
12660                         &window);
12661
12662       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
12663       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
12664
12665       hbox = gtk_hbox_new (FALSE, 0);
12666       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
12667                           TRUE, TRUE, 0);
12668       gtk_widget_show (hbox);
12669
12670       drawing_area = gtk_drawing_area_new ();
12671       gtk_widget_set_size_request (drawing_area, 200, 200);
12672       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
12673       gtk_widget_show (drawing_area);
12674
12675       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
12676
12677       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
12678       scroll_test_pos = 0.0;
12679
12680       scrollbar = gtk_vscrollbar_new (adj);
12681       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
12682       gtk_widget_show (scrollbar);
12683
12684       g_signal_connect (drawing_area, "expose_event",
12685                         G_CALLBACK (scroll_test_expose), adj);
12686       g_signal_connect (drawing_area, "configure_event",
12687                         G_CALLBACK (scroll_test_configure), adj);
12688       g_signal_connect (drawing_area, "scroll_event",
12689                         G_CALLBACK (scroll_test_scroll), adj);
12690       
12691       g_signal_connect (adj, "value_changed",
12692                         G_CALLBACK (scroll_test_adjustment_changed),
12693                         drawing_area);
12694       
12695       /* .. And create some buttons */
12696
12697       button = gtk_button_new_with_label ("Quit");
12698       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
12699                           button, TRUE, TRUE, 0);
12700
12701       g_signal_connect_swapped (button, "clicked",
12702                                 G_CALLBACK (gtk_widget_destroy),
12703                                 window);
12704       gtk_widget_show (button);
12705
12706       /* Set up gridded geometry */
12707
12708       geometry_mask = GDK_HINT_MIN_SIZE | 
12709                        GDK_HINT_BASE_SIZE | 
12710                        GDK_HINT_RESIZE_INC;
12711
12712       geometry.min_width = 20;
12713       geometry.min_height = 20;
12714       geometry.base_width = 0;
12715       geometry.base_height = 0;
12716       geometry.width_inc = 10;
12717       geometry.height_inc = 10;
12718       
12719       gtk_window_set_geometry_hints (GTK_WINDOW (window),
12720                                drawing_area, &geometry, geometry_mask);
12721     }
12722
12723   if (!GTK_WIDGET_VISIBLE (window))
12724     gtk_widget_show (window);
12725   else
12726     gtk_widget_destroy (window);
12727 }
12728
12729 /*
12730  * Timeout Test
12731  */
12732
12733 static int timer = 0;
12734
12735 gint
12736 timeout_test (GtkWidget *label)
12737 {
12738   static int count = 0;
12739   static char buffer[32];
12740
12741   sprintf (buffer, "count: %d", ++count);
12742   gtk_label_set_text (GTK_LABEL (label), buffer);
12743
12744   return TRUE;
12745 }
12746
12747 void
12748 start_timeout_test (GtkWidget *widget,
12749                     GtkWidget *label)
12750 {
12751   if (!timer)
12752     {
12753       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
12754     }
12755 }
12756
12757 void
12758 stop_timeout_test (GtkWidget *widget,
12759                    gpointer   data)
12760 {
12761   if (timer)
12762     {
12763       gtk_timeout_remove (timer);
12764       timer = 0;
12765     }
12766 }
12767
12768 void
12769 destroy_timeout_test (GtkWidget  *widget,
12770                       GtkWidget **window)
12771 {
12772   stop_timeout_test (NULL, NULL);
12773
12774   *window = NULL;
12775 }
12776
12777 void
12778 create_timeout_test (GtkWidget *widget)
12779 {
12780   static GtkWidget *window = NULL;
12781   GtkWidget *button;
12782   GtkWidget *label;
12783
12784   if (!window)
12785     {
12786       window = gtk_dialog_new ();
12787
12788       gtk_window_set_screen (GTK_WINDOW (window),
12789                              gtk_widget_get_screen (widget));
12790
12791       g_signal_connect (window, "destroy",
12792                         G_CALLBACK (destroy_timeout_test),
12793                         &window);
12794
12795       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
12796       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
12797
12798       label = gtk_label_new ("count: 0");
12799       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
12800       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
12801                           label, TRUE, TRUE, 0);
12802       gtk_widget_show (label);
12803
12804       button = gtk_button_new_with_label ("close");
12805       g_signal_connect_swapped (button, "clicked",
12806                                 G_CALLBACK (gtk_widget_destroy),
12807                                 window);
12808       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12809       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12810                           button, TRUE, TRUE, 0);
12811       gtk_widget_grab_default (button);
12812       gtk_widget_show (button);
12813
12814       button = gtk_button_new_with_label ("start");
12815       g_signal_connect (button, "clicked",
12816                         G_CALLBACK(start_timeout_test),
12817                         label);
12818       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12819       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12820                           button, TRUE, TRUE, 0);
12821       gtk_widget_show (button);
12822
12823       button = gtk_button_new_with_label ("stop");
12824       g_signal_connect (button, "clicked",
12825                         G_CALLBACK (stop_timeout_test),
12826                         NULL);
12827       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12828       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12829                           button, TRUE, TRUE, 0);
12830       gtk_widget_show (button);
12831     }
12832
12833   if (!GTK_WIDGET_VISIBLE (window))
12834     gtk_widget_show (window);
12835   else
12836     gtk_widget_destroy (window);
12837 }
12838
12839 /*
12840  * Idle Test
12841  */
12842
12843 static int idle_id = 0;
12844
12845 static gint
12846 idle_test (GtkWidget *label)
12847 {
12848   static int count = 0;
12849   static char buffer[32];
12850
12851   sprintf (buffer, "count: %d", ++count);
12852   gtk_label_set_text (GTK_LABEL (label), buffer);
12853
12854   return TRUE;
12855 }
12856
12857 static void
12858 start_idle_test (GtkWidget *widget,
12859                  GtkWidget *label)
12860 {
12861   if (!idle_id)
12862     {
12863       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
12864     }
12865 }
12866
12867 static void
12868 stop_idle_test (GtkWidget *widget,
12869                 gpointer   data)
12870 {
12871   if (idle_id)
12872     {
12873       gtk_idle_remove (idle_id);
12874       idle_id = 0;
12875     }
12876 }
12877
12878 static void
12879 destroy_idle_test (GtkWidget  *widget,
12880                    GtkWidget **window)
12881 {
12882   stop_idle_test (NULL, NULL);
12883
12884   *window = NULL;
12885 }
12886
12887 static void
12888 toggle_idle_container (GObject *button,
12889                        GtkContainer *container)
12890 {
12891   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (g_object_get_data (button, "user_data")));
12892 }
12893
12894 static void
12895 create_idle_test (GtkWidget *widget)
12896 {
12897   static GtkWidget *window = NULL;
12898   GtkWidget *button;
12899   GtkWidget *label;
12900   GtkWidget *container;
12901
12902   if (!window)
12903     {
12904       GtkWidget *button2;
12905       GtkWidget *frame;
12906       GtkWidget *box;
12907
12908       window = gtk_dialog_new ();
12909
12910       gtk_window_set_screen (GTK_WINDOW (window),
12911                              gtk_widget_get_screen (widget));
12912
12913       g_signal_connect (window, "destroy",
12914                         G_CALLBACK (destroy_idle_test),
12915                         &window);
12916
12917       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
12918       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
12919
12920       label = gtk_label_new ("count: 0");
12921       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
12922       gtk_widget_show (label);
12923       
12924       container =
12925         gtk_widget_new (GTK_TYPE_HBOX,
12926                         "visible", TRUE,
12927                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
12928                          * "GtkWidget::visible", TRUE,
12929                          */
12930                          "child", label,
12931                         /* NULL), */
12932                         NULL);
12933       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
12934                           container, TRUE, TRUE, 0);
12935
12936       frame =
12937         gtk_widget_new (GTK_TYPE_FRAME,
12938                         "border_width", 5,
12939                         "label", "Label Container",
12940                         "visible", TRUE,
12941                         "parent", GTK_DIALOG (window)->vbox,
12942                         NULL);
12943       box =
12944         gtk_widget_new (GTK_TYPE_VBOX,
12945                         "visible", TRUE,
12946                         "parent", frame,
12947                         NULL);
12948       button =
12949         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
12950                                           "label", "Resize-Parent",
12951                                           "user_data", (void*)GTK_RESIZE_PARENT,
12952                                           "visible", TRUE,
12953                                           "parent", box,
12954                                           NULL),
12955                           "signal::clicked", toggle_idle_container, container,
12956                           NULL);
12957       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
12958                                "label", "Resize-Queue",
12959                                "user_data", (void*)GTK_RESIZE_QUEUE,
12960                                "group", button,
12961                                "visible", TRUE,
12962                                "parent", box,
12963                                NULL);
12964       g_object_connect (button,
12965                         "signal::clicked", toggle_idle_container, container,
12966                         NULL);
12967       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
12968                                 "label", "Resize-Immediate",
12969                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
12970                                 NULL);
12971       g_object_connect (button2,
12972                         "signal::clicked", toggle_idle_container, container,
12973                         NULL);
12974       g_object_set (button2,
12975                     "group", button,
12976                     "visible", TRUE,
12977                     "parent", box,
12978                     NULL);
12979
12980       button = gtk_button_new_with_label ("close");
12981       g_signal_connect_swapped (button, "clicked",
12982                                 G_CALLBACK (gtk_widget_destroy),
12983                                 window);
12984       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12985       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12986                           button, TRUE, TRUE, 0);
12987       gtk_widget_grab_default (button);
12988       gtk_widget_show (button);
12989
12990       button = gtk_button_new_with_label ("start");
12991       g_signal_connect (button, "clicked",
12992                         G_CALLBACK (start_idle_test),
12993                         label);
12994       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12995       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
12996                           button, TRUE, TRUE, 0);
12997       gtk_widget_show (button);
12998
12999       button = gtk_button_new_with_label ("stop");
13000       g_signal_connect (button, "clicked",
13001                         G_CALLBACK (stop_idle_test),
13002                         NULL);
13003       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13004       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
13005                           button, TRUE, TRUE, 0);
13006       gtk_widget_show (button);
13007     }
13008
13009   if (!GTK_WIDGET_VISIBLE (window))
13010     gtk_widget_show (window);
13011   else
13012     gtk_widget_destroy (window);
13013 }
13014
13015 /*
13016  * rc file test
13017  */
13018
13019 void
13020 reload_all_rc_files (void)
13021 {
13022   static GdkAtom atom_rcfiles = GDK_NONE;
13023
13024   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
13025   int i;
13026   
13027   if (!atom_rcfiles)
13028     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
13029
13030   for(i = 0; i < 5; i++)
13031     send_event->client.data.l[i] = 0;
13032   send_event->client.data_format = 32;
13033   send_event->client.message_type = atom_rcfiles;
13034   gdk_event_send_clientmessage_toall (send_event);
13035
13036   gdk_event_free (send_event);
13037 }
13038
13039 void
13040 create_rc_file (GtkWidget *widget)
13041 {
13042   static GtkWidget *window = NULL;
13043   GtkWidget *button;
13044   GtkWidget *frame;
13045   GtkWidget *vbox;
13046   GtkWidget *label;
13047
13048   if (!window)
13049     {
13050       window = gtk_dialog_new ();
13051
13052       gtk_window_set_screen (GTK_WINDOW (window),
13053                              gtk_widget_get_screen (widget));
13054
13055       g_signal_connect (window, "destroy",
13056                         G_CALLBACK (gtk_widget_destroyed),
13057                         &window);
13058
13059       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
13060       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
13061
13062       vbox = gtk_vbox_new (FALSE, 0);
13063       gtk_container_add (GTK_CONTAINER (frame), vbox);
13064       
13065       label = gtk_label_new ("This label should be red");
13066       gtk_widget_set_name (label, "testgtk-red-label");
13067       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13068
13069       label = gtk_label_new ("This label should be green");
13070       gtk_widget_set_name (label, "testgtk-green-label");
13071       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13072
13073       label = gtk_label_new ("This label should be blue");
13074       gtk_widget_set_name (label, "testgtk-blue-label");
13075       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13076
13077       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
13078       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
13079
13080       button = gtk_button_new_with_label ("Reload");
13081       g_signal_connect (button, "clicked",
13082                         G_CALLBACK (gtk_rc_reparse_all), NULL);
13083       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13084       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
13085                           button, TRUE, TRUE, 0);
13086       gtk_widget_grab_default (button);
13087
13088       button = gtk_button_new_with_label ("Reload All");
13089       g_signal_connect (button, "clicked",
13090                         G_CALLBACK (reload_all_rc_files), NULL);
13091       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13092       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
13093                           button, TRUE, TRUE, 0);
13094
13095       button = gtk_button_new_with_label ("Close");
13096       g_signal_connect_swapped (button, "clicked",
13097                                 G_CALLBACK (gtk_widget_destroy),
13098                                 window);
13099       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13100       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
13101                           button, TRUE, TRUE, 0);
13102     }
13103
13104   if (!GTK_WIDGET_VISIBLE (window))
13105     gtk_widget_show_all (window);
13106   else
13107     gtk_widget_destroy (window);
13108 }
13109
13110 /*
13111  * Test of recursive mainloop
13112  */
13113
13114 void
13115 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
13116 {
13117   *window = NULL;
13118   gtk_main_quit ();
13119 }
13120
13121 void
13122 create_mainloop (GtkWidget *widget)
13123 {
13124   static GtkWidget *window = NULL;
13125   GtkWidget *label;
13126   GtkWidget *button;
13127
13128   if (!window)
13129     {
13130       window = gtk_dialog_new ();
13131
13132       gtk_window_set_screen (GTK_WINDOW (window),
13133                              gtk_widget_get_screen (widget));
13134
13135       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
13136
13137       g_signal_connect (window, "destroy",
13138                         G_CALLBACK (mainloop_destroyed),
13139                         &window);
13140
13141       label = gtk_label_new ("In recursive main loop...");
13142       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
13143
13144       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
13145                           TRUE, TRUE, 0);
13146       gtk_widget_show (label);
13147
13148       button = gtk_button_new_with_label ("Leave");
13149       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
13150                           FALSE, TRUE, 0);
13151
13152       g_signal_connect_swapped (button, "clicked",
13153                                 G_CALLBACK (gtk_widget_destroy),
13154                                 window);
13155
13156       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13157       gtk_widget_grab_default (button);
13158
13159       gtk_widget_show (button);
13160     }
13161
13162   if (!GTK_WIDGET_VISIBLE (window))
13163     {
13164       gtk_widget_show (window);
13165
13166       g_print ("create_mainloop: start\n");
13167       gtk_main ();
13168       g_print ("create_mainloop: done\n");
13169     }
13170   else
13171     gtk_widget_destroy (window);
13172 }
13173
13174 gboolean
13175 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
13176 {
13177   GtkLayout *layout;
13178
13179   gint i,j;
13180   gint imin, imax, jmin, jmax;
13181
13182   layout = GTK_LAYOUT (widget);
13183
13184   if (event->window != layout->bin_window)
13185     return FALSE;
13186   
13187   imin = (event->area.x) / 10;
13188   imax = (event->area.x + event->area.width + 9) / 10;
13189
13190   jmin = (event->area.y) / 10;
13191   jmax = (event->area.y + event->area.height + 9) / 10;
13192
13193   for (i=imin; i<imax; i++)
13194     for (j=jmin; j<jmax; j++)
13195       if ((i+j) % 2)
13196         gdk_draw_rectangle (layout->bin_window,
13197                             widget->style->black_gc,
13198                             TRUE,
13199                             10*i, 10*j, 
13200                             1+i%10, 1+j%10);
13201   
13202   return FALSE;
13203 }
13204
13205 void create_layout (GtkWidget *widget)
13206 {
13207   static GtkWidget *window = NULL;
13208   GtkWidget *layout;
13209   GtkWidget *scrolledwindow;
13210   GtkWidget *button;
13211
13212   if (!window)
13213     {
13214       gchar buf[16];
13215
13216       gint i, j;
13217       
13218       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
13219       gtk_window_set_screen (GTK_WINDOW (window),
13220                              gtk_widget_get_screen (widget));
13221
13222       g_signal_connect (window, "destroy",
13223                         G_CALLBACK (gtk_widget_destroyed),
13224                         &window);
13225
13226       gtk_window_set_title (GTK_WINDOW (window), "Layout");
13227       gtk_widget_set_size_request (window, 200, 200);
13228
13229       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
13230       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
13231                                            GTK_SHADOW_IN);
13232       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
13233                                          GTK_CORNER_TOP_RIGHT);
13234
13235       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
13236       
13237       layout = gtk_layout_new (NULL, NULL);
13238       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
13239
13240       /* We set step sizes here since GtkLayout does not set
13241        * them itself.
13242        */
13243       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
13244       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
13245       
13246       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
13247       g_signal_connect (layout, "expose_event",
13248                         G_CALLBACK (layout_expose_handler), NULL);
13249       
13250       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
13251       
13252       for (i=0 ; i < 16 ; i++)
13253         for (j=0 ; j < 16 ; j++)
13254           {
13255             sprintf(buf, "Button %d, %d", i, j);
13256             if ((i + j) % 2)
13257               button = gtk_button_new_with_label (buf);
13258             else
13259               button = gtk_label_new (buf);
13260
13261             gtk_layout_put (GTK_LAYOUT (layout), button,
13262                             j*100, i*100);
13263           }
13264
13265       for (i=16; i < 1280; i++)
13266         {
13267           sprintf(buf, "Button %d, %d", i, 0);
13268           if (i % 2)
13269             button = gtk_button_new_with_label (buf);
13270           else
13271             button = gtk_label_new (buf);
13272
13273           gtk_layout_put (GTK_LAYOUT (layout), button,
13274                           0, i*100);
13275         }
13276     }
13277
13278   if (!GTK_WIDGET_VISIBLE (window))
13279     gtk_widget_show_all (window);
13280   else
13281     gtk_widget_destroy (window);
13282 }
13283
13284 void
13285 create_styles (GtkWidget *widget)
13286 {
13287   static GtkWidget *window = NULL;
13288   GtkWidget *label;
13289   GtkWidget *button;
13290   GtkWidget *entry;
13291   GtkWidget *vbox;
13292   static GdkColor red =    { 0, 0xffff, 0,      0      };
13293   static GdkColor green =  { 0, 0,      0xffff, 0      };
13294   static GdkColor blue =   { 0, 0,      0,      0xffff };
13295   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
13296   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
13297   PangoFontDescription *font_desc;
13298
13299   GtkRcStyle *rc_style;
13300
13301   if (!window)
13302     {
13303       window = gtk_dialog_new ();
13304       gtk_window_set_screen (GTK_WINDOW (window),
13305                              gtk_widget_get_screen (widget));
13306      
13307       g_signal_connect (window, "destroy",
13308                         G_CALLBACK (gtk_widget_destroyed),
13309                         &window);
13310
13311       
13312       button = gtk_button_new_with_label ("Close");
13313       g_signal_connect_swapped (button, "clicked",
13314                                 G_CALLBACK (gtk_widget_destroy),
13315                                 window);
13316       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13317       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
13318                           button, TRUE, TRUE, 0);
13319       gtk_widget_show (button);
13320
13321       vbox = gtk_vbox_new (FALSE, 5);
13322       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
13323       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
13324       
13325       label = gtk_label_new ("Font:");
13326       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13327       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13328
13329       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
13330
13331       button = gtk_button_new_with_label ("Some Text");
13332       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
13333       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
13334
13335       label = gtk_label_new ("Foreground:");
13336       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13337       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13338
13339       button = gtk_button_new_with_label ("Some Text");
13340       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
13341       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
13342
13343       label = gtk_label_new ("Background:");
13344       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13345       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13346
13347       button = gtk_button_new_with_label ("Some Text");
13348       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
13349       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
13350
13351       label = gtk_label_new ("Text:");
13352       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13353       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13354
13355       entry = gtk_entry_new ();
13356       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
13357       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
13358       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
13359
13360       label = gtk_label_new ("Base:");
13361       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13362       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13363
13364       entry = gtk_entry_new ();
13365       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
13366       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
13367       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
13368
13369       label = gtk_label_new ("Multiple:");
13370       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
13371       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
13372
13373       button = gtk_button_new_with_label ("Some Text");
13374
13375       rc_style = gtk_rc_style_new ();
13376
13377       rc_style->font_desc = pango_font_description_copy (font_desc);
13378       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
13379       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
13380       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
13381       rc_style->fg[GTK_STATE_NORMAL] = yellow;
13382       rc_style->bg[GTK_STATE_NORMAL] = blue;
13383       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
13384       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
13385       rc_style->fg[GTK_STATE_ACTIVE] = red;
13386       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
13387       rc_style->xthickness = 5;
13388       rc_style->ythickness = 5;
13389
13390       gtk_widget_modify_style (button, rc_style);
13391       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
13392
13393       g_object_unref (rc_style);
13394       
13395       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
13396     }
13397   
13398   if (!GTK_WIDGET_VISIBLE (window))
13399     gtk_widget_show_all (window);
13400   else
13401     gtk_widget_destroy (window);
13402 }
13403
13404 /*
13405  * Main Window and Exit
13406  */
13407
13408 void
13409 do_exit (GtkWidget *widget, GtkWidget *window)
13410 {
13411   gtk_widget_destroy (window);
13412   gtk_main_quit ();
13413 }
13414
13415 struct {
13416   char *label;
13417   void (*func) (GtkWidget *widget);
13418   gboolean do_not_benchmark;
13419 } buttons[] =
13420 {
13421   { "alpha window", create_alpha_window },
13422 #ifdef G_OS_WIN32
13423   /* dog slow on NT, no working at all on 9x */
13424   { "big windows", create_big_windows, TRUE },
13425 #else
13426   { "big windows", create_big_windows },
13427 #endif
13428   { "button box", create_button_box },
13429   { "buttons", create_buttons },
13430   { "check buttons", create_check_buttons },
13431   { "clist", create_clist},
13432   { "color selection", create_color_selection },
13433   { "composited window", create_composited_window },
13434   { "ctree", create_ctree },
13435   { "cursors", create_cursors },
13436   { "dialog", create_dialog, TRUE },
13437   { "display & screen", create_display_screen, TRUE },
13438   { "entry", create_entry },
13439   { "event box", create_event_box },
13440   { "event watcher", create_event_watcher },
13441   { "expander", create_expander },
13442   { "file selection", create_file_selection },
13443   { "flipping", create_flipping },
13444   { "focus", create_focus },
13445   { "font selection", create_font_selection },
13446   { "gamma curve", create_gamma_curve, TRUE },
13447   { "gridded geometry", create_gridded_geometry },
13448   { "handle box", create_handle_box },
13449   { "image from drawable", create_get_image },
13450   { "image", create_image },
13451   { "item factory", create_item_factory },
13452   { "key lookup", create_key_lookup },
13453   { "labels", create_labels },
13454   { "layout", create_layout },
13455   { "list", create_list },
13456   { "menus", create_menus },
13457   { "message dialog", create_message_dialog },
13458   { "modal window", create_modal_window, TRUE },
13459   { "notebook", create_notebook },
13460   { "panes", create_panes },
13461   { "paned keyboard", create_paned_keyboard_navigation },
13462   { "pixmap", create_pixmap },
13463   { "preview color", create_color_preview, TRUE },
13464   { "preview gray", create_gray_preview, TRUE },
13465   { "progress bar", create_progress_bar },
13466   { "properties", create_properties },
13467   { "radio buttons", create_radio_buttons },
13468   { "range controls", create_range_controls },
13469   { "rc file", create_rc_file },
13470   { "reparent", create_reparent },
13471   { "resize grips", create_resize_grips },
13472   { "rotated label", create_rotated_label },
13473   { "rotated text", create_rotated_text },
13474   { "rulers", create_rulers },
13475   { "saved position", create_saved_position },
13476   { "scrolled windows", create_scrolled_windows },
13477   { "shapes", create_shapes },
13478   { "size groups", create_size_groups },
13479   { "spinbutton", create_spins },
13480   { "statusbar", create_statusbar },
13481   { "styles", create_styles },
13482   { "test idle", create_idle_test },
13483   { "test mainloop", create_mainloop, TRUE },
13484   { "test scrolling", create_scroll_test },
13485   { "test selection", create_selection_test },
13486   { "test timeout", create_timeout_test },
13487   { "text", create_text },
13488   { "toggle buttons", create_toggle_buttons },
13489   { "toolbar", create_toolbar },
13490   { "tooltips", create_tooltips },
13491   { "tree", create_tree_mode_window},
13492   { "WM hints", create_wmhints },
13493   { "window sizing", create_window_sizing },
13494   { "window states", create_window_states }
13495 };
13496 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
13497
13498 void
13499 create_main_window (void)
13500 {
13501   GtkWidget *window;
13502   GtkWidget *box1;
13503   GtkWidget *box2;
13504   GtkWidget *scrolled_window;
13505   GtkWidget *button;
13506   GtkWidget *label;
13507   gchar buffer[64];
13508   GtkWidget *separator;
13509   GdkGeometry geometry;
13510   int i;
13511
13512   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
13513   gtk_widget_set_name (window, "main window");
13514   gtk_widget_set_uposition (window, 20, 20);
13515   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
13516
13517   geometry.min_width = -1;
13518   geometry.min_height = -1;
13519   geometry.max_width = -1;
13520   geometry.max_height = G_MAXSHORT;
13521   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
13522                                  &geometry,
13523                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
13524
13525   g_signal_connect (window, "destroy",
13526                     G_CALLBACK (gtk_main_quit),
13527                     NULL);
13528   g_signal_connect (window, "delete-event",
13529                     G_CALLBACK (gtk_false),
13530                     NULL);
13531
13532   box1 = gtk_vbox_new (FALSE, 0);
13533   gtk_container_add (GTK_CONTAINER (window), box1);
13534
13535   if (gtk_micro_version > 0)
13536     sprintf (buffer,
13537              "Gtk+ v%d.%d.%d",
13538              gtk_major_version,
13539              gtk_minor_version,
13540              gtk_micro_version);
13541   else
13542     sprintf (buffer,
13543              "Gtk+ v%d.%d",
13544              gtk_major_version,
13545              gtk_minor_version);
13546
13547   label = gtk_label_new (buffer);
13548   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
13549   gtk_widget_set_name (label, "testgtk-version-label");
13550
13551   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
13552   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
13553   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
13554                                   GTK_POLICY_NEVER, 
13555                                   GTK_POLICY_AUTOMATIC);
13556   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
13557
13558   box2 = gtk_vbox_new (FALSE, 0);
13559   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
13560   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
13561   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
13562                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
13563   gtk_widget_show (box2);
13564
13565   for (i = 0; i < nbuttons; i++)
13566     {
13567       button = gtk_button_new_with_label (buttons[i].label);
13568       if (buttons[i].func)
13569         g_signal_connect (button, 
13570                           "clicked", 
13571                           G_CALLBACK(buttons[i].func),
13572                           NULL);
13573       else
13574         gtk_widget_set_sensitive (button, FALSE);
13575       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
13576     }
13577
13578   separator = gtk_hseparator_new ();
13579   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
13580
13581   box2 = gtk_vbox_new (FALSE, 10);
13582   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
13583   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
13584
13585   button = gtk_button_new_with_mnemonic ("_Close");
13586   g_signal_connect (button, "clicked",
13587                     G_CALLBACK (do_exit),
13588                     window);
13589   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
13590   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
13591   gtk_widget_grab_default (button);
13592
13593   gtk_widget_show_all (window);
13594 }
13595
13596 static void
13597 test_init (void)
13598 {
13599   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
13600                    G_FILE_TEST_EXISTS))
13601     {
13602       g_setenv ("GDK_PIXBUF_MODULE_FILE", "../gdk-pixbuf/gdk-pixbuf.loaders", TRUE);
13603       g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/gtk.immodules", TRUE);
13604     }
13605 }
13606
13607 static char *
13608 pad (const char *str, int to)
13609 {
13610   static char buf[256];
13611   int len = strlen (str);
13612   int i;
13613
13614   for (i = 0; i < to; i++)
13615     buf[i] = ' ';
13616
13617   buf[to] = '\0';
13618
13619   memcpy (buf, str, len);
13620
13621   return buf;
13622 }
13623
13624 static void
13625 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
13626 {
13627   fn (widget); /* on */
13628   while (g_main_context_iteration (NULL, FALSE));
13629   fn (widget); /* off */
13630   while (g_main_context_iteration (NULL, FALSE));
13631 }
13632
13633 void
13634 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
13635 {
13636   GTimeVal tv0, tv1;
13637   double dt_first;
13638   double dt;
13639   int n;
13640   static gboolean printed_headers = FALSE;
13641
13642   if (!printed_headers) {
13643     g_print ("Test                 Iters      First      Other\n");
13644     g_print ("-------------------- ----- ---------- ----------\n");
13645     printed_headers = TRUE;
13646   }
13647
13648   g_get_current_time (&tv0);
13649   bench_iteration (widget, fn); 
13650   g_get_current_time (&tv1);
13651
13652   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
13653         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
13654
13655   g_get_current_time (&tv0);
13656   for (n = 0; n < num - 1; n++)
13657     bench_iteration (widget, fn); 
13658   g_get_current_time (&tv1);
13659   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
13660         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
13661
13662   g_print ("%s %5d ", pad (name, 20), num);
13663   if (num > 1)
13664     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
13665   else
13666     g_print ("%10.1f\n", dt_first);
13667 }
13668
13669 void
13670 do_bench (char* what, int num)
13671 {
13672   int i;
13673   GtkWidget *widget;
13674   void (* fn) (GtkWidget *widget);
13675   fn = NULL;
13676   widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
13677
13678   if (g_ascii_strcasecmp (what, "ALL") == 0)
13679     {
13680       for (i = 0; i < nbuttons; i++)
13681         {
13682           if (!buttons[i].do_not_benchmark)
13683             do_real_bench (widget, buttons[i].func, buttons[i].label, num);
13684         }
13685
13686       return;
13687     }
13688   else
13689     {
13690       for (i = 0; i < nbuttons; i++)
13691         {
13692           if (strcmp (buttons[i].label, what) == 0)
13693             {
13694               fn = buttons[i].func;
13695               break;
13696             }
13697         }
13698       
13699       if (!fn)
13700         g_print ("Can't bench: \"%s\" not found.\n", what);
13701       else
13702         do_real_bench (widget, fn, buttons[i].label, num);
13703     }
13704 }
13705
13706 void 
13707 usage (void)
13708 {
13709   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
13710   exit (1);
13711 }
13712
13713 int
13714 main (int argc, char *argv[])
13715 {
13716   GtkBindingSet *binding_set;
13717   int i;
13718   gboolean done_benchmarks = FALSE;
13719
13720   srand (time (NULL));
13721
13722   test_init ();
13723
13724   /* Check to see if we are being run from the correct
13725    * directory.
13726    */
13727   if (file_exists ("testgtkrc"))
13728     gtk_rc_add_default_file ("testgtkrc");
13729
13730   g_set_application_name ("GTK+ Test Program");
13731
13732   gtk_init (&argc, &argv);
13733
13734   gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
13735                                         GDK_CONTROL_MASK |
13736                                         GDK_MOD1_MASK | 
13737                                         GDK_META_MASK |
13738                                         GDK_SUPER_MASK |
13739                                         GDK_HYPER_MASK |
13740                                         GDK_MOD4_MASK);
13741   /*  benchmarking
13742    */
13743   for (i = 1; i < argc; i++)
13744     {
13745       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
13746         {
13747           int num = 1;
13748           char *nextarg;
13749           char *what;
13750           char *count;
13751           
13752           nextarg = strchr (argv[i], '=');
13753           if (nextarg)
13754             nextarg++;
13755           else
13756             {
13757               i++;
13758               if (i == argc)
13759                 usage ();
13760               nextarg = argv[i];
13761             }
13762
13763           count = strchr (nextarg, ':');
13764           if (count)
13765             {
13766               what = g_strndup (nextarg, count - nextarg);
13767               count++;
13768               num = atoi (count);
13769               if (num <= 0)
13770                 usage ();
13771             }
13772           else
13773             what = g_strdup (nextarg);
13774
13775           do_bench (what, num ? num : 1);
13776           done_benchmarks = TRUE;
13777         }
13778       else
13779         usage ();
13780     }
13781   if (done_benchmarks)
13782     return 0;
13783
13784   /* bindings test
13785    */
13786   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
13787   gtk_binding_entry_add_signal (binding_set,
13788                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
13789                                 "debug_msg",
13790                                 1,
13791                                 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
13792   
13793   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
13794    * changes
13795    */
13796
13797   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
13798                        "   fg[NORMAL] = \"#ff0000\"\n"
13799                        "   font = \"Sans 18\"\n"
13800                        "}\n"
13801                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
13802   
13803   create_main_window ();
13804
13805   gtk_main ();
13806
13807   if (1)
13808     {
13809       while (g_main_context_pending (NULL))
13810         g_main_context_iteration (NULL, FALSE);
13811 #if 0
13812       sleep (1);
13813       while (g_main_context_pending (NULL))
13814         g_main_context_iteration (NULL, FALSE);
13815 #endif
13816     }
13817   return 0;
13818 }