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