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