]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
2bbaadd68a6a515dce2ac77ed4560b5ed10211e6
[~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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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-1999.  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 #include "gtk.h"
42 #include "gdk/gdk.h"
43 #include "gdk/gdkkeysyms.h"
44
45 #include "circles.xbm"
46
47 typedef struct _OptionMenuItem
48 {
49   gchar        *name;
50   GtkSignalFunc func;
51 } OptionMenuItem;
52
53 GtkWidget *
54 shape_create_icon (char     *xpm_file,
55                    gint      x,
56                    gint      y,
57                    gint      px,
58                    gint      py,
59                    gint      window_type);
60
61 static GtkWidget *
62 build_option_menu (OptionMenuItem items[],
63                    gint           num_items,
64                    gint           history,
65                    gpointer       data);
66
67 /* macro, structure and variables used by tree window demos */
68 #define DEFAULT_NUMBER_OF_ITEM  3
69 #define DEFAULT_RECURSION_LEVEL 3
70
71 struct {
72   GSList* selection_mode_group;
73   GtkWidget* single_button;
74   GtkWidget* browse_button;
75   GtkWidget* multiple_button;
76   GtkWidget* draw_line_button;
77   GtkWidget* view_line_button;
78   GtkWidget* no_root_item_button;
79   GtkWidget* nb_item_spinner;
80   GtkWidget* recursion_spinner;
81 } sTreeSampleSelection;
82
83 typedef struct sTreeButtons {
84   guint nb_item_add;
85   GtkWidget* add_button;
86   GtkWidget* remove_button;
87   GtkWidget* subtree_button;
88 } sTreeButtons;
89 /* end of tree section */
90
91 static GtkWidget *
92 build_option_menu (OptionMenuItem items[],
93                    gint           num_items,
94                    gint           history,
95                    gpointer       data)
96 {
97   GtkWidget *omenu;
98   GtkWidget *menu;
99   GtkWidget *menu_item;
100   GSList *group;
101   gint i;
102
103   omenu = gtk_option_menu_new ();
104       
105   menu = gtk_menu_new ();
106   group = NULL;
107   
108   for (i = 0; i < num_items; i++)
109     {
110       menu_item = gtk_radio_menu_item_new_with_label (group, items[i].name);
111       gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
112                           (GtkSignalFunc) items[i].func, data);
113       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
114       gtk_menu_append (GTK_MENU (menu), menu_item);
115       if (i == history)
116         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
117       gtk_widget_show (menu_item);
118     }
119
120   gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
121   gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), history);
122   
123   return omenu;
124 }
125
126 static void
127 destroy_tooltips (GtkWidget *widget, GtkWindow **window)
128 {
129   GtkTooltips *tt = gtk_object_get_data (GTK_OBJECT (*window), "tooltips");
130   gtk_object_unref (GTK_OBJECT (tt));
131   *window = NULL;
132 }
133
134 /*
135  * GtkButton
136  */
137
138 static void
139 button_window (GtkWidget *widget,
140                GtkWidget *button)
141 {
142   if (!GTK_WIDGET_VISIBLE (button))
143     gtk_widget_show (button);
144   else
145     gtk_widget_hide (button);
146 }
147
148 static void
149 create_buttons (void)
150 {
151   static GtkWidget *window = NULL;
152   GtkWidget *box1;
153   GtkWidget *box2;
154   GtkWidget *table;
155   GtkWidget *button[10];
156   GtkWidget *separator;
157
158   if (!window)
159     {
160       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
161
162       gtk_signal_connect (GTK_OBJECT (window), "destroy",
163                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
164                           &window);
165
166       gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
167       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
168
169       box1 = gtk_vbox_new (FALSE, 0);
170       gtk_container_add (GTK_CONTAINER (window), box1);
171
172       table = gtk_table_new (3, 3, FALSE);
173       gtk_table_set_row_spacings (GTK_TABLE (table), 5);
174       gtk_table_set_col_spacings (GTK_TABLE (table), 5);
175       gtk_container_set_border_width (GTK_CONTAINER (table), 10);
176       gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
177
178       button[0] = gtk_button_new_with_label ("button1");
179       button[1] = gtk_button_new_with_label ("button2");
180       button[2] = gtk_button_new_with_label ("button3");
181       button[3] = gtk_button_new_with_label ("button4");
182       button[4] = gtk_button_new_with_label ("button5");
183       button[5] = gtk_button_new_with_label ("button6");
184       button[6] = gtk_button_new_with_label ("button7");
185       button[7] = gtk_button_new_with_label ("button8");
186       button[8] = gtk_button_new_with_label ("button9");
187
188       gtk_signal_connect (GTK_OBJECT (button[0]), "clicked",
189                           GTK_SIGNAL_FUNC(button_window),
190                           button[1]);
191
192       gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
193                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
194
195       gtk_signal_connect (GTK_OBJECT (button[1]), "clicked",
196                           GTK_SIGNAL_FUNC(button_window),
197                           button[2]);
198
199       gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
200                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
201
202       gtk_signal_connect (GTK_OBJECT (button[2]), "clicked",
203                           GTK_SIGNAL_FUNC(button_window),
204                           button[3]);
205       gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
206                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
207
208       gtk_signal_connect (GTK_OBJECT (button[3]), "clicked",
209                           GTK_SIGNAL_FUNC(button_window),
210                           button[4]);
211       gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
212                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
213
214       gtk_signal_connect (GTK_OBJECT (button[4]), "clicked",
215                           GTK_SIGNAL_FUNC(button_window),
216                           button[5]);
217       gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
218                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
219
220       gtk_signal_connect (GTK_OBJECT (button[5]), "clicked",
221                           GTK_SIGNAL_FUNC(button_window),
222                           button[6]);
223       gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
224                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
225
226       gtk_signal_connect (GTK_OBJECT (button[6]), "clicked",
227                           GTK_SIGNAL_FUNC(button_window),
228                           button[7]);
229       gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
230                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
231
232       gtk_signal_connect (GTK_OBJECT (button[7]), "clicked",
233                           GTK_SIGNAL_FUNC(button_window),
234                           button[8]);
235       gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
236                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
237
238       gtk_signal_connect (GTK_OBJECT (button[8]), "clicked",
239                           GTK_SIGNAL_FUNC(button_window),
240                           button[0]);
241       gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
242                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
243
244       separator = gtk_hseparator_new ();
245       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
246
247       box2 = gtk_vbox_new (FALSE, 10);
248       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
249       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
250
251       button[9] = gtk_button_new_with_label ("close");
252       gtk_signal_connect_object (GTK_OBJECT (button[9]), "clicked",
253                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
254                                  GTK_OBJECT (window));
255       gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
256       GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
257       gtk_widget_grab_default (button[9]);
258     }
259
260   if (!GTK_WIDGET_VISIBLE (window))
261     gtk_widget_show_all (window);
262   else
263     gtk_widget_destroy (window);
264 }
265
266 /*
267  * GtkToggleButton
268  */
269
270 static void
271 create_toggle_buttons (void)
272 {
273   static GtkWidget *window = NULL;
274   GtkWidget *box1;
275   GtkWidget *box2;
276   GtkWidget *button;
277   GtkWidget *separator;
278
279   if (!window)
280     {
281       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
282
283       gtk_signal_connect (GTK_OBJECT (window), "destroy",
284                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
285                           &window);
286
287       gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
288       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
289
290       box1 = gtk_vbox_new (FALSE, 0);
291       gtk_container_add (GTK_CONTAINER (window), box1);
292
293       box2 = gtk_vbox_new (FALSE, 10);
294       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
295       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
296
297       button = gtk_toggle_button_new_with_label ("button1");
298       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
299
300       button = gtk_toggle_button_new_with_label ("button2");
301       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
302
303       button = gtk_toggle_button_new_with_label ("button3");
304       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
305
306       separator = gtk_hseparator_new ();
307       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
308
309       box2 = gtk_vbox_new (FALSE, 10);
310       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
311       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
312
313       button = gtk_button_new_with_label ("close");
314       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
315                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
316                                  GTK_OBJECT (window));
317       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
318       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
319       gtk_widget_grab_default (button);
320     }
321
322   if (!GTK_WIDGET_VISIBLE (window))
323     gtk_widget_show_all (window);
324   else
325     gtk_widget_destroy (window);
326 }
327
328 /*
329  * GtkCheckButton
330  */
331
332 static void
333 create_check_buttons (void)
334 {
335   static GtkWidget *window = NULL;
336   GtkWidget *box1;
337   GtkWidget *box2;
338   GtkWidget *button;
339   GtkWidget *separator;
340
341   if (!window)
342     {
343       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
344
345       gtk_signal_connect (GTK_OBJECT (window), "destroy",
346                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
347                           &window);
348
349       gtk_window_set_title (GTK_WINDOW (window), "GtkCheckButton");
350       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
351
352       box1 = gtk_vbox_new (FALSE, 0);
353       gtk_container_add (GTK_CONTAINER (window), box1);
354
355       box2 = gtk_vbox_new (FALSE, 10);
356       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
357       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
358
359       button = gtk_check_button_new_with_label ("button1");
360       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
361
362       button = gtk_check_button_new_with_label ("button2");
363       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
364
365       button = gtk_check_button_new_with_label ("button3");
366       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
367
368       separator = gtk_hseparator_new ();
369       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
370
371       box2 = gtk_vbox_new (FALSE, 10);
372       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
373       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
374
375       button = gtk_button_new_with_label ("close");
376       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
377                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
378                                  GTK_OBJECT (window));
379       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
380       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
381       gtk_widget_grab_default (button);
382     }
383
384   if (!GTK_WIDGET_VISIBLE (window))
385     gtk_widget_show_all (window);
386   else
387     gtk_widget_destroy (window);
388 }
389
390 /*
391  * GtkRadioButton
392  */
393
394 static void
395 create_radio_buttons (void)
396 {
397   static GtkWidget *window = NULL;
398   GtkWidget *box1;
399   GtkWidget *box2;
400   GtkWidget *button;
401   GtkWidget *separator;
402
403   if (!window)
404     {
405       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
406
407       gtk_signal_connect (GTK_OBJECT (window), "destroy",
408                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
409                           &window);
410
411       gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
412       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
413
414       box1 = gtk_vbox_new (FALSE, 0);
415       gtk_container_add (GTK_CONTAINER (window), box1);
416
417       box2 = gtk_vbox_new (FALSE, 10);
418       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
419       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
420
421       button = gtk_radio_button_new_with_label (NULL, "button1");
422       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
423
424       button = gtk_radio_button_new_with_label (
425                  gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
426                  "button2");
427       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
428       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
429
430       button = gtk_radio_button_new_with_label (
431                  gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
432                  "button3");
433       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
434
435       separator = gtk_hseparator_new ();
436       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
437
438       box2 = gtk_vbox_new (FALSE, 10);
439       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
440       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
441
442       button = gtk_button_new_with_label ("close");
443       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
444                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
445                                  GTK_OBJECT (window));
446       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
447       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
448       gtk_widget_grab_default (button);
449     }
450
451   if (!GTK_WIDGET_VISIBLE (window))
452     gtk_widget_show_all (window);
453   else
454     gtk_widget_destroy (window);
455 }
456
457 /*
458  * GtkButtonBox
459  */
460
461 static GtkWidget *
462 create_bbox (gint  horizontal,
463              char* title, 
464              gint  spacing,
465              gint  child_w, 
466              gint  child_h, 
467              gint  layout)
468 {
469   GtkWidget *frame;
470   GtkWidget *bbox;
471   GtkWidget *button;
472         
473   frame = gtk_frame_new (title);
474
475   if (horizontal)
476     bbox = gtk_hbutton_box_new ();
477   else
478     bbox = gtk_vbutton_box_new ();
479
480   gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
481   gtk_container_add (GTK_CONTAINER (frame), bbox);
482
483   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
484   gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), spacing);
485   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
486   
487   button = gtk_button_new_with_label ("OK");
488   gtk_container_add (GTK_CONTAINER (bbox), button);
489   
490   button = gtk_button_new_with_label ("Cancel");
491   gtk_container_add (GTK_CONTAINER (bbox), button);
492   
493   button = gtk_button_new_with_label ("Help");
494   gtk_container_add (GTK_CONTAINER (bbox), button);
495
496   return frame;
497 }
498
499 static void
500 create_button_box (void)
501 {
502   static GtkWidget* window = NULL;
503   GtkWidget *main_vbox;
504   GtkWidget *vbox;
505   GtkWidget *hbox;
506   GtkWidget *frame_horz;
507   GtkWidget *frame_vert;
508         
509   if (!window)
510   {
511     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
512     gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
513     
514     gtk_signal_connect (GTK_OBJECT (window), "destroy",
515                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
516                         &window);
517     
518     gtk_container_set_border_width (GTK_CONTAINER (window), 10);
519
520     main_vbox = gtk_vbox_new (FALSE, 0);
521     gtk_container_add (GTK_CONTAINER (window), main_vbox);
522     
523     frame_horz = gtk_frame_new ("Horizontal Button Boxes");
524     gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
525     
526     vbox = gtk_vbox_new (FALSE, 0);
527     gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
528     gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
529
530     gtk_box_pack_start (GTK_BOX (vbox), 
531            create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
532                         TRUE, TRUE, 0);
533
534     gtk_box_pack_start (GTK_BOX (vbox), 
535            create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
536                         TRUE, TRUE, 5);
537
538     gtk_box_pack_start (GTK_BOX (vbox), 
539            create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
540                         TRUE, TRUE, 5);
541
542     gtk_box_pack_start (GTK_BOX (vbox), 
543            create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
544                         TRUE, TRUE, 5);
545
546     frame_vert = gtk_frame_new ("Vertical Button Boxes");
547     gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
548     
549     hbox = gtk_hbox_new (FALSE, 0);
550     gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
551     gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
552
553     gtk_box_pack_start (GTK_BOX (hbox), 
554            create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
555                         TRUE, TRUE, 0);
556
557     gtk_box_pack_start (GTK_BOX (hbox), 
558            create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
559                         TRUE, TRUE, 5);
560
561     gtk_box_pack_start (GTK_BOX (hbox), 
562            create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
563                         TRUE, TRUE, 5);
564
565     gtk_box_pack_start (GTK_BOX (hbox), 
566            create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
567                         TRUE, TRUE, 5);
568   }
569
570   if (!GTK_WIDGET_VISIBLE (window))
571     gtk_widget_show_all (window);
572   else
573     gtk_widget_destroy (window);
574 }
575
576 /*
577  * GtkToolBar
578  */
579
580 static GtkWidget*
581 new_pixmap (char      *filename,
582             GdkWindow *window,
583             GdkColor  *background)
584 {
585   GtkWidget *wpixmap;
586   GdkPixmap *pixmap;
587   GdkBitmap *mask;
588
589   pixmap = gdk_pixmap_create_from_xpm (window, &mask,
590                                        background,
591                                        filename);
592   wpixmap = gtk_pixmap_new (pixmap, mask);
593
594   return wpixmap;
595 }
596
597 static void
598 set_toolbar_horizontal (GtkWidget *widget,
599                         gpointer   data)
600 {
601   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_HORIZONTAL);
602 }
603
604 static void
605 set_toolbar_vertical (GtkWidget *widget,
606                       gpointer   data)
607 {
608   gtk_toolbar_set_orientation (GTK_TOOLBAR (data), GTK_ORIENTATION_VERTICAL);
609 }
610
611 static void
612 set_toolbar_icons (GtkWidget *widget,
613                    gpointer   data)
614 {
615   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
616 }
617
618 static void
619 set_toolbar_text (GtkWidget *widget,
620                   gpointer   data)
621 {
622   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
623 }
624
625 static void
626 set_toolbar_both (GtkWidget *widget,
627                   gpointer   data)
628 {
629   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
630 }
631
632 static void
633 set_toolbar_both_horiz (GtkWidget *widget,
634                         gpointer   data)
635 {
636   gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH_HORIZ);
637 }
638
639 static void
640 set_toolbar_small_space (GtkWidget *widget,
641                          gpointer   data)
642 {
643   gtk_toolbar_set_space_size (GTK_TOOLBAR (data), 5);
644 }
645
646 static void
647 set_toolbar_big_space (GtkWidget *widget,
648                        gpointer   data)
649 {
650   gtk_toolbar_set_space_size (GTK_TOOLBAR (data), 10);
651 }
652
653 static void
654 set_toolbar_enable (GtkWidget *widget,
655                     gpointer   data)
656 {
657   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), TRUE);
658 }
659
660 static void
661 set_toolbar_disable (GtkWidget *widget,
662                      gpointer   data)
663 {
664   gtk_toolbar_set_tooltips (GTK_TOOLBAR (data), FALSE);
665 }
666
667 static void
668 set_toolbar_borders (GtkWidget *widget,
669                      gpointer   data)
670 {
671   gtk_toolbar_set_button_relief (GTK_TOOLBAR (data), GTK_RELIEF_NORMAL);
672 }
673
674 static void
675 set_toolbar_borderless (GtkWidget *widget,
676                         gpointer   data)
677 {
678   gtk_toolbar_set_button_relief (GTK_TOOLBAR (data), GTK_RELIEF_NONE);
679 }
680
681 static void
682 set_toolbar_space_style_empty (GtkWidget *widget,
683                                gpointer   data)
684 {
685   gtk_toolbar_set_space_style (GTK_TOOLBAR (data), GTK_TOOLBAR_SPACE_EMPTY);
686 }
687
688 static void
689 set_toolbar_space_style_line (GtkWidget *widget,
690                               gpointer   data)
691 {
692   gtk_toolbar_set_space_style (GTK_TOOLBAR (data), GTK_TOOLBAR_SPACE_LINE);
693 }
694
695 static void
696 create_toolbar (void)
697 {
698   static GtkWidget *window = NULL;
699   GtkWidget *toolbar;
700   GtkWidget *entry;
701
702   if (!window)
703     {
704       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
705       gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
706       gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, TRUE);
707
708       gtk_signal_connect (GTK_OBJECT (window), "destroy",
709                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
710                           &window);
711
712       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
713       gtk_widget_realize (window);
714
715       toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
716       gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
717
718       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
719                                "Horizontal", "Horizontal toolbar layout", "Toolbar/Horizontal",
720                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
721                                (GtkSignalFunc) set_toolbar_horizontal, toolbar);
722       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
723                                "Vertical", "Vertical toolbar layout", "Toolbar/Vertical",
724                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
725                                (GtkSignalFunc) set_toolbar_vertical, toolbar);
726
727       gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
728
729       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
730                                "Icons", "Only show toolbar icons", "Toolbar/IconsOnly",
731                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
732                                (GtkSignalFunc) set_toolbar_icons, toolbar);
733       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
734                                "Text", "Only show toolbar text", "Toolbar/TextOnly",
735                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
736                                (GtkSignalFunc) set_toolbar_text, toolbar);
737       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
738                                "Both", "Show toolbar icons and text", "Toolbar/Both",
739                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
740                                (GtkSignalFunc) set_toolbar_both, toolbar);
741       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
742                                "Both (horizontal)",
743                                "Show toolbar icons and text in a horizontal fashion",
744                                "Toolbar/BothHoriz",
745                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
746                                (GtkSignalFunc) set_toolbar_both_horiz, toolbar);
747                                
748       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
749
750       entry = gtk_entry_new ();
751
752       gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), entry, "This is an unusable GtkEntry ;)", "Hey don't click me!!!");
753
754       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
755
756       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
757                                "Small", "Use small spaces", "Toolbar/Small",
758                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
759                                (GtkSignalFunc) set_toolbar_small_space, toolbar);
760       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
761                                "Big", "Use big spaces", "Toolbar/Big",
762                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
763                                (GtkSignalFunc) set_toolbar_big_space, toolbar);
764
765       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
766
767       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
768                                "Enable", "Enable tooltips", NULL,
769                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
770                                (GtkSignalFunc) set_toolbar_enable, toolbar);
771       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
772                                "Disable", "Disable tooltips", NULL,
773                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
774                                (GtkSignalFunc) set_toolbar_disable, toolbar);
775
776       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
777
778       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
779                                "Borders", "Show Borders", NULL,
780                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
781                                (GtkSignalFunc) set_toolbar_borders, toolbar);
782       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
783                                "Borderless", "Hide Borders", NULL,
784                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
785                                (GtkSignalFunc) set_toolbar_borderless, toolbar);
786
787       gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
788       
789       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
790                                "Empty", "Empty spaces", NULL,
791                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
792                                (GtkSignalFunc) set_toolbar_space_style_empty, toolbar);
793       gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
794                                "Lines", "Lines in spaces", NULL,
795                                new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
796                                (GtkSignalFunc) set_toolbar_space_style_line, toolbar);
797
798       gtk_container_add (GTK_CONTAINER (window), toolbar);
799     }
800
801   if (!GTK_WIDGET_VISIBLE (window))
802     gtk_widget_show_all (window);
803   else
804     gtk_widget_destroy (window);
805 }
806
807 static GtkWidget*
808 make_toolbar (GtkWidget *window)
809 {
810   GtkWidget *toolbar;
811
812   if (!GTK_WIDGET_REALIZED (window))
813     gtk_widget_realize (window);
814
815   toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
816   gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
817
818   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
819                            "Horizontal", "Horizontal toolbar layout", NULL,
820                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
821                            (GtkSignalFunc) set_toolbar_horizontal, toolbar);
822   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
823                            "Vertical", "Vertical toolbar layout", NULL,
824                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
825                            (GtkSignalFunc) set_toolbar_vertical, toolbar);
826
827   gtk_toolbar_append_space (GTK_TOOLBAR(toolbar));
828
829   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
830                            "Icons", "Only show toolbar icons", NULL,
831                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
832                            (GtkSignalFunc) set_toolbar_icons, toolbar);
833   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
834                            "Text", "Only show toolbar text", NULL,
835                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
836                            (GtkSignalFunc) set_toolbar_text, toolbar);
837   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
838                            "Both", "Show toolbar icons and text", NULL,
839                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
840                            (GtkSignalFunc) set_toolbar_both, toolbar);
841
842   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
843
844   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
845                            "Small", "Use small spaces", NULL,
846                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
847                            (GtkSignalFunc) set_toolbar_small_space, toolbar);
848   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
849                            "Big", "Use big spaces", "Toolbar/Big",
850                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
851                            (GtkSignalFunc) set_toolbar_big_space, toolbar);
852
853   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
854
855   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
856                            "Enable", "Enable tooltips", NULL,
857                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
858                            (GtkSignalFunc) set_toolbar_enable, toolbar);
859   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
860                            "Disable", "Disable tooltips", NULL,
861                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
862                            (GtkSignalFunc) set_toolbar_disable, toolbar);
863
864   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
865   
866   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
867                            "Borders", "Show Borders", NULL,
868                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
869                            (GtkSignalFunc) set_toolbar_borders, toolbar);
870   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
871                            "Borderless", "Hide Borders", NULL,
872                            new_pixmap ("test.xpm", window->window, &window->style->bg[GTK_STATE_NORMAL]),
873                            (GtkSignalFunc) set_toolbar_borderless, toolbar);
874
875   return toolbar;
876 }
877
878 /*
879  * GtkStatusBar
880  */
881
882 static guint statusbar_counter = 1;
883
884 static void
885 statusbar_push (GtkWidget *button,
886                 GtkStatusbar *statusbar)
887 {
888   gchar text[1024];
889
890   sprintf (text, "something %d", statusbar_counter++);
891
892   gtk_statusbar_push (statusbar, 1, text);
893 }
894
895 static void
896 statusbar_pop (GtkWidget *button,
897                GtkStatusbar *statusbar)
898 {
899   gtk_statusbar_pop (statusbar, 1);
900 }
901
902 static void
903 statusbar_steal (GtkWidget *button,
904                  GtkStatusbar *statusbar)
905 {
906   gtk_statusbar_remove (statusbar, 1, 4);
907 }
908
909 static void
910 statusbar_popped (GtkStatusbar  *statusbar,
911                   guint          context_id,
912                   const gchar   *text)
913 {
914   if (!statusbar->messages)
915     statusbar_counter = 1;
916 }
917
918 static void
919 statusbar_contexts (GtkStatusbar *statusbar)
920 {
921   gchar *string;
922
923   string = "any context";
924   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
925            string,
926            gtk_statusbar_get_context_id (statusbar, string));
927   
928   string = "idle messages";
929   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
930            string,
931            gtk_statusbar_get_context_id (statusbar, string));
932   
933   string = "some text";
934   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
935            string,
936            gtk_statusbar_get_context_id (statusbar, string));
937
938   string = "hit the mouse";
939   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
940            string,
941            gtk_statusbar_get_context_id (statusbar, string));
942
943   string = "hit the mouse2";
944   g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
945            string,
946            gtk_statusbar_get_context_id (statusbar, string));
947 }
948
949 static void
950 statusbar_dump_stack (GtkStatusbar *statusbar)
951 {
952   GSList *list;
953
954   for (list = statusbar->messages; list; list = list->next)
955     {
956       GtkStatusbarMsg *msg;
957
958       msg = list->data;
959       g_print ("context_id: %d, message_id: %d, status_text: \"%s\"\n",
960                msg->context_id,
961                msg->message_id,
962                msg->text);
963     }
964 }
965
966 static void
967 create_statusbar (void)
968 {
969   static GtkWidget *window = NULL;
970   GtkWidget *box1;
971   GtkWidget *box2;
972   GtkWidget *button;
973   GtkWidget *separator;
974   GtkWidget *statusbar;
975
976   if (!window)
977     {
978       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
979
980       gtk_signal_connect (GTK_OBJECT (window), "destroy",
981                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
982                           &window);
983
984       gtk_window_set_title (GTK_WINDOW (window), "statusbar");
985       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
986
987       box1 = gtk_vbox_new (FALSE, 0);
988       gtk_container_add (GTK_CONTAINER (window), box1);
989
990       box2 = gtk_vbox_new (FALSE, 10);
991       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
992       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
993
994       statusbar = gtk_statusbar_new ();
995       gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
996       gtk_signal_connect (GTK_OBJECT (statusbar),
997                           "text_popped",
998                           GTK_SIGNAL_FUNC (statusbar_popped),
999                           NULL);
1000
1001       button = gtk_widget_new (gtk_button_get_type (),
1002                                "label", "push something",
1003                                "visible", TRUE,
1004                                "parent", box2,
1005                                "signal::clicked", statusbar_push, statusbar,
1006                                NULL);
1007
1008       button = gtk_widget_new (gtk_button_get_type (),
1009                                "label", "pop",
1010                                "visible", TRUE,
1011                                "parent", box2,
1012                                "signal_after::clicked", statusbar_pop, statusbar,
1013                                NULL);
1014
1015       button = gtk_widget_new (gtk_button_get_type (),
1016                                "label", "steal #4",
1017                                "visible", TRUE,
1018                                "parent", box2,
1019                                "signal_after::clicked", statusbar_steal, statusbar,
1020                                NULL);
1021
1022       button = gtk_widget_new (gtk_button_get_type (),
1023                                "label", "dump stack",
1024                                "visible", TRUE,
1025                                "parent", box2,
1026                                "object_signal::clicked", statusbar_dump_stack, statusbar,
1027                                NULL);
1028
1029       button = gtk_widget_new (gtk_button_get_type (),
1030                                "label", "test contexts",
1031                                "visible", TRUE,
1032                                "parent", box2,
1033                                "object_signal_after::clicked", statusbar_contexts, statusbar,
1034                                NULL);
1035
1036       separator = gtk_hseparator_new ();
1037       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1038
1039       box2 = gtk_vbox_new (FALSE, 10);
1040       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1041       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1042
1043       button = gtk_button_new_with_label ("close");
1044       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1045                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1046                                  GTK_OBJECT (window));
1047       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1048       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1049       gtk_widget_grab_default (button);
1050     }
1051
1052   if (!GTK_WIDGET_VISIBLE (window))
1053     gtk_widget_show_all (window);
1054   else
1055     gtk_widget_destroy (window);
1056 }
1057
1058 /*
1059  * GtkTree
1060  */
1061
1062 static void
1063 cb_tree_destroy_event(GtkWidget* w)
1064 {
1065   sTreeButtons* tree_buttons;
1066
1067   /* free buttons structure associate at this tree */
1068   tree_buttons = gtk_object_get_user_data (GTK_OBJECT (w));
1069   g_free (tree_buttons);
1070 }
1071
1072 static void
1073 cb_add_new_item(GtkWidget* w, GtkTree* tree)
1074 {
1075   sTreeButtons* tree_buttons;
1076   GList* selected_list;
1077   GtkWidget* selected_item;
1078   GtkWidget* subtree;
1079   GtkWidget* item_new;
1080   char buffer[255];
1081
1082   tree_buttons = gtk_object_get_user_data(GTK_OBJECT(tree));
1083
1084   selected_list = GTK_TREE_SELECTION(tree);
1085
1086   if(selected_list == NULL)
1087     {
1088       /* there is no item in tree */
1089       subtree = GTK_WIDGET(tree);
1090     }
1091   else
1092     {
1093       /* list can have only one element */
1094       selected_item = GTK_WIDGET(selected_list->data);
1095       
1096       subtree = GTK_TREE_ITEM_SUBTREE(selected_item);
1097
1098       if(subtree == NULL)
1099         {
1100           /* current selected item have not subtree ... create it */
1101           subtree = gtk_tree_new();
1102           gtk_tree_item_set_subtree(GTK_TREE_ITEM(selected_item), 
1103                                     subtree);
1104         }
1105     }
1106
1107   /* at this point, we know which subtree will be used to add new item */
1108   /* create a new item */
1109   sprintf(buffer, "item add %d", tree_buttons->nb_item_add);
1110   item_new = gtk_tree_item_new_with_label(buffer);
1111   gtk_tree_append(GTK_TREE(subtree), item_new);
1112   gtk_widget_show(item_new);
1113
1114   tree_buttons->nb_item_add++;
1115 }
1116
1117 static void
1118 cb_remove_item(GtkWidget*w, GtkTree* tree)
1119 {
1120   GList* selected_list;
1121   GList* clear_list;
1122   
1123   selected_list = GTK_TREE_SELECTION(tree);
1124
1125   clear_list = NULL;
1126     
1127   while (selected_list) 
1128     {
1129       clear_list = g_list_prepend (clear_list, selected_list->data);
1130       selected_list = selected_list->next;
1131     }
1132   
1133   clear_list = g_list_reverse (clear_list);
1134   gtk_tree_remove_items(tree, clear_list);
1135
1136   g_list_free (clear_list);
1137 }
1138
1139 static void
1140 cb_remove_subtree(GtkWidget*w, GtkTree* tree)
1141 {
1142   GList* selected_list;
1143   GtkTreeItem *item;
1144   
1145   selected_list = GTK_TREE_SELECTION(tree);
1146
1147   if (selected_list)
1148     {
1149       item = GTK_TREE_ITEM (selected_list->data);
1150       if (item->subtree)
1151         gtk_tree_item_remove_subtree (item);
1152     }
1153 }
1154
1155 static void
1156 cb_tree_changed(GtkTree* tree)
1157 {
1158   sTreeButtons* tree_buttons;
1159   GList* selected_list;
1160   guint nb_selected;
1161
1162   tree_buttons = gtk_object_get_user_data(GTK_OBJECT(tree));
1163
1164   selected_list = GTK_TREE_SELECTION(tree);
1165   nb_selected = g_list_length(selected_list);
1166
1167   if(nb_selected == 0) 
1168     {
1169       if(tree->children == NULL)
1170         gtk_widget_set_sensitive(tree_buttons->add_button, TRUE);
1171       else
1172         gtk_widget_set_sensitive(tree_buttons->add_button, FALSE);
1173       gtk_widget_set_sensitive(tree_buttons->remove_button, FALSE);
1174       gtk_widget_set_sensitive(tree_buttons->subtree_button, FALSE);
1175     } 
1176   else 
1177     {
1178       gtk_widget_set_sensitive(tree_buttons->remove_button, TRUE);
1179       gtk_widget_set_sensitive(tree_buttons->add_button, (nb_selected == 1));
1180       gtk_widget_set_sensitive(tree_buttons->subtree_button, (nb_selected == 1));
1181     }  
1182 }
1183
1184 static void 
1185 create_subtree(GtkWidget* item, guint level, guint nb_item_max, guint recursion_level_max)
1186 {
1187   GtkWidget* item_subtree;
1188   GtkWidget* item_new;
1189   guint nb_item;
1190   char buffer[255];
1191   int no_root_item;
1192
1193   if(level == recursion_level_max) return;
1194
1195   if(level == -1)
1196     {
1197       /* query with no root item */
1198       level = 0;
1199       item_subtree = item;
1200       no_root_item = 1;
1201     }
1202   else
1203     {
1204       /* query with no root item */
1205       /* create subtree and associate it with current item */
1206       item_subtree = gtk_tree_new();
1207       no_root_item = 0;
1208     }
1209   
1210   for(nb_item = 0; nb_item < nb_item_max; nb_item++)
1211     {
1212       sprintf(buffer, "item %d-%d", level, nb_item);
1213       item_new = gtk_tree_item_new_with_label(buffer);
1214       gtk_tree_append(GTK_TREE(item_subtree), item_new);
1215       create_subtree(item_new, level+1, nb_item_max, recursion_level_max);
1216       gtk_widget_show(item_new);
1217     }
1218
1219   if(!no_root_item)
1220     gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), item_subtree);
1221 }
1222
1223 static void
1224 create_tree_sample(guint selection_mode, 
1225                    guint draw_line, guint view_line, guint no_root_item,
1226                    guint nb_item_max, guint recursion_level_max) 
1227 {
1228   GtkWidget* window;
1229   GtkWidget* box1;
1230   GtkWidget* box2;
1231   GtkWidget* separator;
1232   GtkWidget* button;
1233   GtkWidget* scrolled_win;
1234   GtkWidget* root_tree;
1235   GtkWidget* root_item;
1236   sTreeButtons* tree_buttons;
1237
1238   /* create tree buttons struct */
1239   if ((tree_buttons = g_malloc (sizeof (sTreeButtons))) == NULL)
1240     {
1241       g_error("can't allocate memory for tree structure !\n");
1242       return;
1243     }
1244   tree_buttons->nb_item_add = 0;
1245
1246   /* create top level window */
1247   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1248   gtk_window_set_title(GTK_WINDOW(window), "Tree Sample");
1249   gtk_signal_connect(GTK_OBJECT(window), "destroy",
1250                      (GtkSignalFunc) cb_tree_destroy_event, NULL);
1251   gtk_object_set_user_data(GTK_OBJECT(window), tree_buttons);
1252
1253   box1 = gtk_vbox_new(FALSE, 0);
1254   gtk_container_add(GTK_CONTAINER(window), box1);
1255   gtk_widget_show(box1);
1256
1257   /* create tree box */
1258   box2 = gtk_vbox_new(FALSE, 0);
1259   gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1260   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1261   gtk_widget_show(box2);
1262
1263   /* create scrolled window */
1264   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1265   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
1266                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1267   gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
1268   gtk_widget_set_usize (scrolled_win, 200, 200);
1269   gtk_widget_show (scrolled_win);
1270   
1271   /* create root tree widget */
1272   root_tree = gtk_tree_new();
1273   gtk_signal_connect(GTK_OBJECT(root_tree), "selection_changed",
1274                      (GtkSignalFunc)cb_tree_changed,
1275                      (gpointer)NULL);
1276   gtk_object_set_user_data(GTK_OBJECT(root_tree), tree_buttons);
1277   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), root_tree);
1278   gtk_tree_set_selection_mode(GTK_TREE(root_tree), selection_mode);
1279   gtk_tree_set_view_lines(GTK_TREE(root_tree), draw_line);
1280   gtk_tree_set_view_mode(GTK_TREE(root_tree), !view_line);
1281   gtk_widget_show(root_tree);
1282
1283   if ( no_root_item )
1284     {
1285       /* set root tree to subtree function with root item variable */
1286       root_item = GTK_WIDGET(root_tree);
1287     }
1288   else
1289     {
1290       /* create root tree item widget */
1291       root_item = gtk_tree_item_new_with_label("root item");
1292       gtk_tree_append(GTK_TREE(root_tree), root_item);
1293       gtk_widget_show(root_item);
1294      }
1295   create_subtree(root_item, -no_root_item, nb_item_max, recursion_level_max);
1296
1297   box2 = gtk_vbox_new(FALSE, 0);
1298   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1299   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1300   gtk_widget_show(box2);
1301
1302   button = gtk_button_new_with_label("Add Item");
1303   gtk_widget_set_sensitive(button, FALSE);
1304   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1305                      (GtkSignalFunc) cb_add_new_item, 
1306                      (gpointer)root_tree);
1307   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1308   gtk_widget_show(button);
1309   tree_buttons->add_button = button;
1310
1311   button = gtk_button_new_with_label("Remove Item(s)");
1312   gtk_widget_set_sensitive(button, FALSE);
1313   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1314                      (GtkSignalFunc) cb_remove_item, 
1315                      (gpointer)root_tree);
1316   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1317   gtk_widget_show(button);
1318   tree_buttons->remove_button = button;
1319
1320   button = gtk_button_new_with_label("Remove Subtree");
1321   gtk_widget_set_sensitive(button, FALSE);
1322   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1323                      (GtkSignalFunc) cb_remove_subtree, 
1324                      (gpointer)root_tree);
1325   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1326   gtk_widget_show(button);
1327   tree_buttons->subtree_button = button;
1328
1329   /* create separator */
1330   separator = gtk_hseparator_new();
1331   gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1332   gtk_widget_show(separator);
1333
1334   /* create button box */
1335   box2 = gtk_vbox_new(FALSE, 0);
1336   gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1337   gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1338   gtk_widget_show(box2);
1339
1340   button = gtk_button_new_with_label("Close");
1341   gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1342   gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
1343                             (GtkSignalFunc) gtk_widget_destroy, 
1344                             GTK_OBJECT(window));
1345   gtk_widget_show(button);
1346
1347   gtk_widget_show(window);
1348 }
1349
1350 static void
1351 cb_create_tree(GtkWidget* w)
1352 {
1353   guint selection_mode = GTK_SELECTION_SINGLE;
1354   guint view_line;
1355   guint draw_line;
1356   guint no_root_item;
1357   guint nb_item;
1358   guint recursion_level;
1359
1360   /* get selection mode choice */
1361   if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.single_button)->active)
1362     selection_mode = GTK_SELECTION_SINGLE;
1363   else
1364     if(GTK_TOGGLE_BUTTON(sTreeSampleSelection.browse_button)->active)
1365       selection_mode = GTK_SELECTION_BROWSE;
1366     else
1367       selection_mode = GTK_SELECTION_MULTIPLE;
1368
1369   /* get options choice */
1370   draw_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.draw_line_button)->active;
1371   view_line = GTK_TOGGLE_BUTTON(sTreeSampleSelection.view_line_button)->active;
1372   no_root_item = GTK_TOGGLE_BUTTON(sTreeSampleSelection.no_root_item_button)->active;
1373     
1374   /* get levels */
1375   nb_item = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.nb_item_spinner));
1376   recursion_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(sTreeSampleSelection.recursion_spinner));
1377
1378   if (pow (nb_item, recursion_level) > 10000)
1379     {
1380       g_print ("%g total items? That will take a very long time. Try less\n",
1381                pow (nb_item, recursion_level));
1382       return;
1383     }
1384
1385   create_tree_sample(selection_mode, draw_line, view_line, no_root_item, nb_item, recursion_level);
1386 }
1387
1388 void 
1389 create_tree_mode_window(void)
1390 {
1391   static GtkWidget* window;
1392   GtkWidget* box1;
1393   GtkWidget* box2;
1394   GtkWidget* box3;
1395   GtkWidget* box4;
1396   GtkWidget* box5;
1397   GtkWidget* button;
1398   GtkWidget* frame;
1399   GtkWidget* separator;
1400   GtkWidget* label;
1401   GtkWidget* spinner;
1402   GtkAdjustment *adj;
1403
1404   if (!window)
1405     {
1406       /* create toplevel window  */
1407       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1408       gtk_window_set_title(GTK_WINDOW(window), "Set Tree Parameters");
1409       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1410                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1411                           &window);
1412       box1 = gtk_vbox_new(FALSE, 0);
1413       gtk_container_add(GTK_CONTAINER(window), box1);
1414
1415       /* create upper box - selection box */
1416       box2 = gtk_vbox_new(FALSE, 5);
1417       gtk_box_pack_start(GTK_BOX(box1), box2, TRUE, TRUE, 0);
1418       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1419
1420       box3 = gtk_hbox_new(FALSE, 5);
1421       gtk_box_pack_start(GTK_BOX(box2), box3, TRUE, TRUE, 0);
1422
1423       /* create selection mode frame */
1424       frame = gtk_frame_new("Selection Mode");
1425       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1426
1427       box4 = gtk_vbox_new(FALSE, 0);
1428       gtk_container_add(GTK_CONTAINER(frame), box4);
1429       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1430
1431       /* create radio button */  
1432       button = gtk_radio_button_new_with_label(NULL, "SINGLE");
1433       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1434       sTreeSampleSelection.single_button = button;
1435
1436       button = gtk_radio_button_new_with_label(gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
1437                                                "BROWSE");
1438       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1439       sTreeSampleSelection.browse_button = button;
1440
1441       button = gtk_radio_button_new_with_label(gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
1442                                                "MULTIPLE");
1443       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1444       sTreeSampleSelection.multiple_button = button;
1445
1446       sTreeSampleSelection.selection_mode_group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
1447
1448       /* create option mode frame */
1449       frame = gtk_frame_new("Options");
1450       gtk_box_pack_start(GTK_BOX(box3), frame, TRUE, TRUE, 0);
1451
1452       box4 = gtk_vbox_new(FALSE, 0);
1453       gtk_container_add(GTK_CONTAINER(frame), box4);
1454       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1455
1456       /* create check button */
1457       button = gtk_check_button_new_with_label("Draw line");
1458       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1459       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
1460       sTreeSampleSelection.draw_line_button = button;
1461   
1462       button = gtk_check_button_new_with_label("View Line mode");
1463       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1464       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
1465       sTreeSampleSelection.view_line_button = button;
1466   
1467       button = gtk_check_button_new_with_label("Without Root item");
1468       gtk_box_pack_start(GTK_BOX(box4), button, TRUE, TRUE, 0);
1469       sTreeSampleSelection.no_root_item_button = button;
1470
1471       /* create recursion parameter */
1472       frame = gtk_frame_new("Size Parameters");
1473       gtk_box_pack_start(GTK_BOX(box2), frame, TRUE, TRUE, 0);
1474
1475       box4 = gtk_hbox_new(FALSE, 5);
1476       gtk_container_add(GTK_CONTAINER(frame), box4);
1477       gtk_container_set_border_width(GTK_CONTAINER(box4), 5);
1478
1479       /* create number of item spin button */
1480       box5 = gtk_hbox_new(FALSE, 5);
1481       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1482
1483       label = gtk_label_new("Number of items : ");
1484       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1485       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1486
1487       adj = (GtkAdjustment *) gtk_adjustment_new ((gfloat)DEFAULT_NUMBER_OF_ITEM, 1.0, 255.0, 1.0,
1488                                                   5.0, 0.0);
1489       spinner = gtk_spin_button_new (adj, 0, 0);
1490       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1491       sTreeSampleSelection.nb_item_spinner = spinner;
1492   
1493       /* create recursion level spin button */
1494       box5 = gtk_hbox_new(FALSE, 5);
1495       gtk_box_pack_start(GTK_BOX(box4), box5, FALSE, FALSE, 0);
1496
1497       label = gtk_label_new("Depth : ");
1498       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1499       gtk_box_pack_start (GTK_BOX (box5), label, FALSE, TRUE, 0);
1500
1501       adj = (GtkAdjustment *) gtk_adjustment_new ((gfloat)DEFAULT_RECURSION_LEVEL, 0.0, 255.0, 1.0,
1502                                                   5.0, 0.0);
1503       spinner = gtk_spin_button_new (adj, 0, 0);
1504       gtk_box_pack_start (GTK_BOX (box5), spinner, FALSE, TRUE, 0);
1505       sTreeSampleSelection.recursion_spinner = spinner;
1506   
1507       /* create horizontal separator */
1508       separator = gtk_hseparator_new();
1509       gtk_box_pack_start(GTK_BOX(box1), separator, FALSE, FALSE, 0);
1510
1511       /* create bottom button box */
1512       box2 = gtk_hbox_new(TRUE, 10);
1513       gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);
1514       gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
1515
1516       button = gtk_button_new_with_label("Create Tree");
1517       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1518       gtk_signal_connect(GTK_OBJECT (button), "clicked",
1519                          (GtkSignalFunc) cb_create_tree, NULL);
1520
1521       button = gtk_button_new_with_label("Close");
1522       gtk_box_pack_start(GTK_BOX(box2), button, TRUE, TRUE, 0);
1523       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1524                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1525                                  GTK_OBJECT (window));
1526     }
1527   if (!GTK_WIDGET_VISIBLE (window))
1528     gtk_widget_show_all (window);
1529   else
1530     gtk_widget_destroy (window);
1531 }
1532
1533 /*
1534  * GtkHandleBox
1535  */
1536
1537 static void
1538 handle_box_child_signal (GtkHandleBox *hb,
1539                          GtkWidget    *child,
1540                          const gchar  *action)
1541 {
1542   printf ("%s: child <%s> %sed\n",
1543           gtk_type_name (GTK_OBJECT_TYPE (hb)),
1544           gtk_type_name (GTK_OBJECT_TYPE (child)),
1545           action);
1546 }
1547
1548 static void
1549 create_handle_box (void)
1550 {
1551   static GtkWidget* window = NULL;
1552   GtkWidget *handle_box;
1553   GtkWidget *handle_box2;
1554   GtkWidget *vbox;
1555   GtkWidget *hbox;
1556   GtkWidget *toolbar;
1557   GtkWidget *label;
1558   GtkWidget *separator;
1559         
1560   if (!window)
1561   {
1562     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1563     gtk_window_set_title (GTK_WINDOW (window),
1564                           "Handle Box Test");
1565     gtk_window_set_policy (GTK_WINDOW (window),
1566                            TRUE,
1567                            TRUE,
1568                            TRUE);
1569     
1570     gtk_signal_connect (GTK_OBJECT (window), "destroy",
1571                         GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1572                         &window);
1573     
1574     gtk_container_set_border_width (GTK_CONTAINER (window), 20);
1575
1576     vbox = gtk_vbox_new (FALSE, 0);
1577     gtk_container_add (GTK_CONTAINER (window), vbox);
1578     gtk_widget_show (vbox);
1579
1580     label = gtk_label_new ("Above");
1581     gtk_container_add (GTK_CONTAINER (vbox), label);
1582     gtk_widget_show (label);
1583
1584     separator = gtk_hseparator_new ();
1585     gtk_container_add (GTK_CONTAINER (vbox), separator);
1586     gtk_widget_show (separator);
1587     
1588     hbox = gtk_hbox_new (FALSE, 10);
1589     gtk_container_add (GTK_CONTAINER (vbox), hbox);
1590     gtk_widget_show (hbox);
1591
1592     separator = gtk_hseparator_new ();
1593     gtk_container_add (GTK_CONTAINER (vbox), separator);
1594     gtk_widget_show (separator);
1595
1596     label = gtk_label_new ("Below");
1597     gtk_container_add (GTK_CONTAINER (vbox), label);
1598     gtk_widget_show (label);
1599
1600     handle_box = gtk_handle_box_new ();
1601     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
1602     gtk_signal_connect (GTK_OBJECT (handle_box),
1603                         "child_attached",
1604                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1605                         "attached");
1606     gtk_signal_connect (GTK_OBJECT (handle_box),
1607                         "child_detached",
1608                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1609                         "detached");
1610     gtk_widget_show (handle_box);
1611
1612     toolbar = make_toolbar (window);
1613     gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
1614     gtk_container_add (GTK_CONTAINER (handle_box), toolbar);
1615     gtk_widget_show (toolbar);
1616
1617     handle_box = gtk_handle_box_new ();
1618     gtk_box_pack_start (GTK_BOX (hbox), handle_box, FALSE, FALSE, 0);
1619     gtk_signal_connect (GTK_OBJECT (handle_box),
1620                         "child_attached",
1621                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1622                         "attached");
1623     gtk_signal_connect (GTK_OBJECT (handle_box),
1624                         "child_detached",
1625                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1626                         "detached");
1627     gtk_widget_show (handle_box);
1628
1629     handle_box2 = gtk_handle_box_new ();
1630     gtk_container_add (GTK_CONTAINER (handle_box), handle_box2);
1631     gtk_signal_connect (GTK_OBJECT (handle_box2),
1632                         "child_attached",
1633                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1634                         "attached");
1635     gtk_signal_connect (GTK_OBJECT (handle_box2),
1636                         "child_detached",
1637                         GTK_SIGNAL_FUNC (handle_box_child_signal),
1638                         "detached");
1639     gtk_widget_show (handle_box2);
1640
1641     label = gtk_label_new ("Fooo!");
1642     gtk_container_add (GTK_CONTAINER (handle_box2), label);
1643     gtk_widget_show (label);
1644   }
1645
1646   if (!GTK_WIDGET_VISIBLE (window))
1647     gtk_widget_show (window);
1648   else
1649     gtk_widget_destroy (window);
1650 }
1651
1652 /* 
1653  * Label Demo
1654  */
1655 void create_labels (void)
1656 {
1657   static GtkWidget *window = NULL;
1658   GtkWidget *hbox;
1659   GtkWidget *vbox;
1660   GtkWidget *frame;
1661   GtkWidget *label;
1662
1663   if (!window)
1664     {
1665       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1666       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1667                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1668                           &window);
1669
1670       gtk_window_set_title (GTK_WINDOW (window), "Label");
1671       vbox = gtk_vbox_new (FALSE, 5);
1672       hbox = gtk_hbox_new (FALSE, 5);
1673       gtk_container_add (GTK_CONTAINER (window), hbox);
1674       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
1675       gtk_container_set_border_width (GTK_CONTAINER (window), 5);
1676
1677       frame = gtk_frame_new ("Normal Label");
1678       label = gtk_label_new ("This is a Normal label");
1679       gtk_container_add (GTK_CONTAINER (frame), label);
1680       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1681
1682       frame = gtk_frame_new ("Multi-line Label");
1683       label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
1684       gtk_container_add (GTK_CONTAINER (frame), label);
1685       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1686
1687       frame = gtk_frame_new ("Left Justified Label");
1688       label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird      line");
1689       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1690       gtk_container_add (GTK_CONTAINER (frame), label);
1691       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1692
1693       frame = gtk_frame_new ("Right Justified Label");
1694       label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
1695       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
1696       gtk_container_add (GTK_CONTAINER (frame), label);
1697       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1698
1699       vbox = gtk_vbox_new (FALSE, 5);
1700       gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
1701       frame = gtk_frame_new ("Line wrapped label");
1702       label = gtk_label_new ("This is an example of a line-wrapped label.  It should not be taking "\
1703                              "up the entire             "/* big space to test spacing */\
1704                              "width allocated to it, but automatically wraps the words to fit.  "\
1705                              "The time has come, for all good men, to come to the aid of their party.  "\
1706                              "The sixth sheik's six sheep's sick.\n"\
1707                              "     It supports multiple paragraphs correctly, and  correctly   adds "\
1708                              "many          extra  spaces. ");
1709
1710       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1711       gtk_container_add (GTK_CONTAINER (frame), label);
1712       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1713
1714       frame = gtk_frame_new ("Filled, wrapped label");
1715       label = gtk_label_new ("This is an example of a line-wrapped, filled label.  It should be taking "\
1716                              "up the entire              width allocated to it.  Here is a seneance to prove "\
1717                              "my point.  Here is another sentence. "\
1718                              "Here comes the sun, do de do de do.\n"\
1719                              "    This is a new paragraph.\n"\
1720                              "    This is another newer, longer, better paragraph.  It is coming to an end, "\
1721                              "unfortunately.");
1722       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
1723       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1724       gtk_container_add (GTK_CONTAINER (frame), label);
1725       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1726
1727       frame = gtk_frame_new ("Underlined label");
1728       label = gtk_label_new ("This label is underlined!\n"
1729                              "This one is underlined in ÆüËܸì¤ÎÆþÍÑquite a funky fashion");
1730       gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1731       gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __  ___ ____ _____");
1732       gtk_container_add (GTK_CONTAINER (frame), label);
1733       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1734
1735     }
1736   if (!GTK_WIDGET_VISIBLE (window))
1737     gtk_widget_show_all (window);
1738   else
1739     gtk_widget_destroy (window);
1740 }
1741
1742 /*
1743  * Reparent demo
1744  */
1745
1746 static void
1747 reparent_label (GtkWidget *widget,
1748                 GtkWidget *new_parent)
1749 {
1750   GtkWidget *label;
1751
1752   label = gtk_object_get_user_data (GTK_OBJECT (widget));
1753
1754   gtk_widget_reparent (label, new_parent);
1755 }
1756
1757 static void
1758 set_parent_signal (GtkWidget *child,
1759                    GtkWidget *old_parent,
1760                    gpointer   func_data)
1761 {
1762   g_print ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
1763            gtk_type_name (GTK_OBJECT_TYPE (child)),
1764            child->parent ? gtk_type_name (GTK_OBJECT_TYPE (child->parent)) : "NULL",
1765            old_parent ? gtk_type_name (GTK_OBJECT_TYPE (old_parent)) : "NULL",
1766            GPOINTER_TO_INT (func_data));
1767 }
1768
1769 static void
1770 create_reparent (void)
1771 {
1772   static GtkWidget *window = NULL;
1773   GtkWidget *box1;
1774   GtkWidget *box2;
1775   GtkWidget *box3;
1776   GtkWidget *frame;
1777   GtkWidget *button;
1778   GtkWidget *label;
1779   GtkWidget *separator;
1780
1781   if (!window)
1782     {
1783       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1784
1785       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1786                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1787                           &window);
1788
1789       gtk_window_set_title (GTK_WINDOW (window), "reparent");
1790       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1791
1792       box1 = gtk_vbox_new (FALSE, 0);
1793       gtk_container_add (GTK_CONTAINER (window), box1);
1794
1795       box2 = gtk_hbox_new (FALSE, 5);
1796       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1797       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1798
1799       label = gtk_label_new ("Hello World");
1800
1801       frame = gtk_frame_new ("Frame 1");
1802       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
1803
1804       box3 = gtk_vbox_new (FALSE, 5);
1805       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
1806       gtk_container_add (GTK_CONTAINER (frame), box3);
1807
1808       button = gtk_button_new_with_label ("switch");
1809       gtk_signal_connect (GTK_OBJECT (button), "clicked",
1810                           GTK_SIGNAL_FUNC(reparent_label),
1811                           box3);
1812       gtk_object_set_user_data (GTK_OBJECT (button), label);
1813       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
1814
1815       gtk_box_pack_start (GTK_BOX (box3), label, FALSE, TRUE, 0);
1816       gtk_signal_connect (GTK_OBJECT (label),
1817                           "parent_set",
1818                           GTK_SIGNAL_FUNC (set_parent_signal),
1819                           GINT_TO_POINTER (42));
1820
1821       frame = gtk_frame_new ("Frame 2");
1822       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
1823
1824       box3 = gtk_vbox_new (FALSE, 5);
1825       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
1826       gtk_container_add (GTK_CONTAINER (frame), box3);
1827
1828       button = gtk_button_new_with_label ("switch");
1829       gtk_signal_connect (GTK_OBJECT (button), "clicked",
1830                           GTK_SIGNAL_FUNC(reparent_label),
1831                           box3);
1832       gtk_object_set_user_data (GTK_OBJECT (button), label);
1833       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
1834
1835       separator = gtk_hseparator_new ();
1836       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1837
1838       box2 = gtk_vbox_new (FALSE, 10);
1839       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1840       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1841
1842       button = gtk_button_new_with_label ("close");
1843       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1844                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
1845                                  GTK_OBJECT (window));
1846       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1847       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1848       gtk_widget_grab_default (button);
1849     }
1850
1851   if (!GTK_WIDGET_VISIBLE (window))
1852     gtk_widget_show_all (window);
1853   else
1854     gtk_widget_destroy (window);
1855 }
1856
1857 /*
1858  * Saved Position
1859  */
1860 gint upositionx = 0;
1861 gint upositiony = 0;
1862
1863 static gint
1864 uposition_configure (GtkWidget *window)
1865 {
1866   GtkLabel *lx;
1867   GtkLabel *ly;
1868   gchar buffer[64];
1869
1870   lx = gtk_object_get_data (GTK_OBJECT (window), "x");
1871   ly = gtk_object_get_data (GTK_OBJECT (window), "y");
1872
1873   gdk_window_get_root_origin (window->window, &upositionx, &upositiony);
1874   sprintf (buffer, "%d", upositionx);
1875   gtk_label_set_text (lx, buffer);
1876   sprintf (buffer, "%d", upositiony);
1877   gtk_label_set_text (ly, buffer);
1878
1879   return FALSE;
1880 }
1881
1882 static void
1883 create_saved_position (void)
1884 {
1885   static GtkWidget *window = NULL;
1886
1887   if (!window)
1888     {
1889       GtkWidget *hbox;
1890       GtkWidget *main_vbox;
1891       GtkWidget *vbox;
1892       GtkWidget *x_label;
1893       GtkWidget *y_label;
1894       GtkWidget *button;
1895       GtkWidget *label;
1896       GtkWidget *any;
1897
1898       window = gtk_widget_new (GTK_TYPE_WINDOW,
1899                                "type", GTK_WINDOW_TOPLEVEL,
1900                                "signal::configure_event", uposition_configure, NULL,
1901                                "x", upositionx,
1902                                "y", upositiony,
1903                                "title", "Saved Position",
1904                                NULL);
1905
1906       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1907                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1908                           &window);
1909
1910       main_vbox = gtk_vbox_new (FALSE, 5);
1911       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
1912       gtk_container_add (GTK_CONTAINER (window), main_vbox);
1913
1914       vbox =
1915         gtk_widget_new (gtk_vbox_get_type (),
1916                         "GtkBox::homogeneous", FALSE,
1917                         "GtkBox::spacing", 5,
1918                         "GtkContainer::border_width", 10,
1919                         "GtkWidget::parent", main_vbox,
1920                         "GtkWidget::visible", TRUE,
1921                         NULL);
1922
1923       hbox = gtk_hbox_new (FALSE, 0);
1924       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1925       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1926
1927       label = gtk_label_new ("X Origin : ");
1928       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1929       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
1930
1931       x_label = gtk_label_new ("");
1932       gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
1933       gtk_object_set_data (GTK_OBJECT (window), "x", x_label);
1934
1935       hbox = gtk_hbox_new (FALSE, 0);
1936       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
1937       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
1938
1939       label = gtk_label_new ("Y Origin : ");
1940       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1941       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
1942
1943       y_label = gtk_label_new ("");
1944       gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
1945       gtk_object_set_data (GTK_OBJECT (window), "y", y_label);
1946
1947       any =
1948         gtk_widget_new (gtk_hseparator_get_type (),
1949                         "GtkWidget::visible", TRUE,
1950                         NULL);
1951       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
1952
1953       hbox = gtk_hbox_new (FALSE, 0);
1954       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1955       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
1956
1957       button = gtk_button_new_with_label ("Close");
1958       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
1959                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
1960                                  GTK_OBJECT (window));
1961       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
1962       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
1963       gtk_widget_grab_default (button);
1964       
1965       gtk_widget_show_all (window);
1966     }
1967   else
1968     gtk_widget_destroy (window);
1969 }
1970
1971 /*
1972  * GtkPixmap
1973  */
1974
1975 static void
1976 create_pixmap (void)
1977 {
1978   static GtkWidget *window = NULL;
1979   GtkWidget *box1;
1980   GtkWidget *box2;
1981   GtkWidget *box3;
1982   GtkWidget *button;
1983   GtkWidget *label;
1984   GtkWidget *separator;
1985   GtkWidget *pixmapwid;
1986   GdkPixmap *pixmap;
1987   GdkBitmap *mask;
1988
1989   if (!window)
1990     {
1991       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1992
1993       gtk_signal_connect (GTK_OBJECT (window), "destroy",
1994                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
1995                           &window);
1996
1997       gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
1998       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1999       gtk_widget_realize(window);
2000
2001       box1 = gtk_vbox_new (FALSE, 0);
2002       gtk_container_add (GTK_CONTAINER (window), box1);
2003
2004       box2 = gtk_vbox_new (FALSE, 10);
2005       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2006       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2007
2008       button = gtk_button_new ();
2009       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2010
2011       pixmap = gdk_pixmap_create_from_xpm (window->window, &mask, NULL,
2012                                            "test.xpm");
2013       pixmapwid = gtk_pixmap_new (pixmap, mask);
2014       gdk_pixmap_unref (pixmap);
2015       gdk_pixmap_unref (mask);
2016
2017       label = gtk_label_new ("Pixmap\ntest");
2018       box3 = gtk_hbox_new (FALSE, 0);
2019       gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2020       gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
2021       gtk_container_add (GTK_CONTAINER (box3), label);
2022       gtk_container_add (GTK_CONTAINER (button), box3);
2023
2024       separator = gtk_hseparator_new ();
2025       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2026
2027       box2 = gtk_vbox_new (FALSE, 10);
2028       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2029       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2030
2031       button = gtk_button_new_with_label ("close");
2032       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2033                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2034                                  GTK_OBJECT (window));
2035       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2036       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2037       gtk_widget_grab_default (button);
2038     }
2039
2040   if (!GTK_WIDGET_VISIBLE (window))
2041     gtk_widget_show_all (window);
2042   else
2043     gtk_widget_destroy (window);
2044 }
2045
2046 static void
2047 tips_query_widget_entered (GtkTipsQuery   *tips_query,
2048                            GtkWidget      *widget,
2049                            const gchar    *tip_text,
2050                            const gchar    *tip_private,
2051                            GtkWidget      *toggle)
2052 {
2053   if (GTK_TOGGLE_BUTTON (toggle)->active)
2054     {
2055       gtk_label_set_text (GTK_LABEL (tips_query), tip_text ? "There is a Tip!" : "There is no Tip!");
2056       /* don't let GtkTipsQuery reset its label */
2057       gtk_signal_emit_stop_by_name (GTK_OBJECT (tips_query), "widget_entered");
2058     }
2059 }
2060
2061 static gint
2062 tips_query_widget_selected (GtkWidget      *tips_query,
2063                             GtkWidget      *widget,
2064                             const gchar    *tip_text,
2065                             const gchar    *tip_private,
2066                             GdkEventButton *event,
2067                             gpointer        func_data)
2068 {
2069   if (widget)
2070     g_print ("Help \"%s\" requested for <%s>\n",
2071              tip_private ? tip_private : "None",
2072              gtk_type_name (GTK_OBJECT_TYPE (widget)));
2073   return TRUE;
2074 }
2075
2076 static void
2077 create_tooltips (void)
2078 {
2079   static GtkWidget *window = NULL;
2080   GtkWidget *box1;
2081   GtkWidget *box2;
2082   GtkWidget *box3;
2083   GtkWidget *button;
2084   GtkWidget *toggle;
2085   GtkWidget *frame;
2086   GtkWidget *tips_query;
2087   GtkWidget *separator;
2088   GtkTooltips *tooltips;
2089
2090   if (!window)
2091     {
2092       window =
2093         gtk_widget_new (gtk_window_get_type (),
2094                         "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
2095                         "GtkContainer::border_width", 0,
2096                         "GtkWindow::title", "Tooltips",
2097                         "GtkWindow::allow_shrink", TRUE,
2098                         "GtkWindow::allow_grow", FALSE,
2099                         "GtkWindow::auto_shrink", TRUE,
2100                         "GtkWidget::width", 200,
2101                         NULL);
2102
2103       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2104                           GTK_SIGNAL_FUNC (destroy_tooltips),
2105                           &window);
2106
2107       tooltips=gtk_tooltips_new();
2108       gtk_object_set_data (GTK_OBJECT (window), "tooltips", tooltips);
2109       
2110       box1 = gtk_vbox_new (FALSE, 0);
2111       gtk_container_add (GTK_CONTAINER (window), box1);
2112
2113       box2 = gtk_vbox_new (FALSE, 10);
2114       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2115       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2116
2117       button = gtk_toggle_button_new_with_label ("button1");
2118       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2119
2120       gtk_tooltips_set_tip (tooltips,button,"This is button 1", "ContextHelp/buttons/1");
2121
2122       button = gtk_toggle_button_new_with_label ("button2");
2123       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2124
2125       gtk_tooltips_set_tip (tooltips,
2126                             button,
2127                             "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.",
2128                             "ContextHelp/buttons/2_long");
2129
2130       toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
2131       gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
2132
2133       gtk_tooltips_set_tip (tooltips, toggle, "Toggle TipsQuery view.", "Hi msw! ;)");
2134
2135       box3 =
2136         gtk_widget_new (gtk_vbox_get_type (),
2137                         "GtkBox::homogeneous", FALSE,
2138                         "GtkBox::spacing", 5,
2139                         "GtkContainer::border_width", 5,
2140                         "GtkWidget::visible", TRUE,
2141                         NULL);
2142
2143       tips_query = gtk_tips_query_new ();
2144
2145       button =
2146         gtk_widget_new (gtk_button_get_type (),
2147                         "GtkButton::label", "[?]",
2148                         "GtkWidget::visible", TRUE,
2149                         "GtkWidget::parent", box3,
2150                         "GtkObject::object_signal::clicked", gtk_tips_query_start_query, tips_query,
2151                         NULL);
2152       gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
2153       gtk_tooltips_set_tip (tooltips,
2154                             button,
2155                             "Start the Tooltips Inspector",
2156                             "ContextHelp/buttons/?");
2157       
2158       
2159       gtk_widget_set (tips_query,
2160                       "GtkWidget::visible", TRUE,
2161                       "GtkWidget::parent", box3,
2162                       "GtkTipsQuery::caller", button,
2163                       "GtkObject::signal::widget_entered", tips_query_widget_entered, toggle,
2164                       "GtkObject::signal::widget_selected", tips_query_widget_selected, NULL,
2165                       NULL);
2166       
2167       frame =
2168         gtk_widget_new (gtk_frame_get_type (),
2169                         "GtkFrame::label", "ToolTips Inspector",
2170                         "GtkFrame::label_xalign", (double) 0.5,
2171                         "GtkContainer::border_width", 0,
2172                         "GtkWidget::visible", TRUE,
2173                         "GtkWidget::parent", box2,
2174                         "GtkContainer::child", box3,
2175                         NULL);
2176       gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
2177
2178       separator = gtk_hseparator_new ();
2179       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2180
2181       box2 = gtk_vbox_new (FALSE, 10);
2182       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2183       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2184
2185       button = gtk_button_new_with_label ("close");
2186       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2187                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2188                                  GTK_OBJECT (window));
2189       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2190       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2191       gtk_widget_grab_default (button);
2192
2193       gtk_tooltips_set_tip (tooltips, button, "Push this button to close window", "ContextHelp/buttons/Close");
2194     }
2195
2196   if (!GTK_WIDGET_VISIBLE (window))
2197     gtk_widget_show_all (window);
2198   else
2199     gtk_widget_destroy (window);
2200 }
2201
2202 /*
2203  * Menu demo
2204  */
2205
2206 static GtkWidget*
2207 create_menu (gint depth, gboolean tearoff)
2208 {
2209   GtkWidget *menu;
2210   GtkWidget *menuitem;
2211   GSList *group;
2212   char buf[32];
2213   int i, j;
2214
2215   if (depth < 1)
2216     return NULL;
2217
2218   menu = gtk_menu_new ();
2219   group = NULL;
2220
2221   if (tearoff)
2222     {
2223       menuitem = gtk_tearoff_menu_item_new ();
2224       gtk_menu_append (GTK_MENU (menu), menuitem);
2225       gtk_widget_show (menuitem);
2226     }
2227
2228   for (i = 0, j = 1; i < 5; i++, j++)
2229     {
2230       sprintf (buf, "item %2d - %d", depth, j);
2231       menuitem = gtk_radio_menu_item_new_with_label (group, buf);
2232       group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
2233       if (depth % 2)
2234         gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (menuitem), TRUE);
2235       gtk_menu_append (GTK_MENU (menu), menuitem);
2236       gtk_widget_show (menuitem);
2237       if (i == 3)
2238         gtk_widget_set_sensitive (menuitem, FALSE);
2239
2240       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (depth - 1, TRUE));
2241     }
2242
2243   return menu;
2244 }
2245
2246 static void
2247 create_menus (void)
2248 {
2249   static GtkWidget *window = NULL;
2250   GtkWidget *box1;
2251   GtkWidget *box2;
2252   GtkWidget *button;
2253   GtkWidget *optionmenu;
2254   GtkWidget *separator;
2255   
2256   if (!window)
2257     {
2258       GtkWidget *menubar;
2259       GtkWidget *menu;
2260       GtkWidget *menuitem;
2261       GtkAccelGroup *accel_group;
2262       
2263       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2264       
2265       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2266                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2267                           &window);
2268       gtk_signal_connect (GTK_OBJECT (window), "delete-event",
2269                           GTK_SIGNAL_FUNC (gtk_true),
2270                           NULL);
2271       
2272       accel_group = gtk_accel_group_new ();
2273       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
2274
2275       gtk_window_set_title (GTK_WINDOW (window), "menus");
2276       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2277       
2278       
2279       box1 = gtk_vbox_new (FALSE, 0);
2280       gtk_container_add (GTK_CONTAINER (window), box1);
2281       gtk_widget_show (box1);
2282       
2283       menubar = gtk_menu_bar_new ();
2284       gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
2285       gtk_widget_show (menubar);
2286       
2287       menu = create_menu (2, TRUE);
2288       
2289       menuitem = gtk_menu_item_new_with_label ("test\nline2");
2290       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
2291       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2292       gtk_widget_show (menuitem);
2293       
2294       menuitem = gtk_menu_item_new_with_label ("foo");
2295       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3, TRUE));
2296       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2297       gtk_widget_show (menuitem);
2298
2299       menuitem = gtk_menu_item_new_with_label ("bar");
2300       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4, TRUE));
2301       gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
2302       gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
2303       gtk_widget_show (menuitem);
2304       
2305       box2 = gtk_vbox_new (FALSE, 10);
2306       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2307       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2308       gtk_widget_show (box2);
2309       
2310       menu = create_menu (1, FALSE);
2311       gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
2312
2313       menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
2314       gtk_menu_append (GTK_MENU (menu), menuitem);
2315       gtk_widget_show (menuitem);
2316       gtk_widget_add_accelerator (menuitem,
2317                                   "activate",
2318                                   accel_group,
2319                                   GDK_F1,
2320                                   0,
2321                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE);
2322       menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
2323       gtk_menu_append (GTK_MENU (menu), menuitem);
2324       gtk_widget_show (menuitem);
2325       gtk_widget_add_accelerator (menuitem,
2326                                   "activate",
2327                                   accel_group,
2328                                   GDK_F2,
2329                                   0,
2330                                   GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
2331       menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
2332       gtk_menu_append (GTK_MENU (menu), menuitem);
2333       gtk_widget_show (menuitem);
2334       gtk_widget_add_accelerator (menuitem,
2335                                   "activate",
2336                                   accel_group,
2337                                   GDK_F2,
2338                                   0,
2339                                   GTK_ACCEL_VISIBLE);
2340       gtk_widget_add_accelerator (menuitem,
2341                                   "activate",
2342                                   accel_group,
2343                                   GDK_F3,
2344                                   0,
2345                                   GTK_ACCEL_VISIBLE);
2346       gtk_widget_lock_accelerators (menuitem);
2347       
2348       optionmenu = gtk_option_menu_new ();
2349       gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
2350       gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 3);
2351       gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
2352       gtk_widget_show (optionmenu);
2353
2354       separator = gtk_hseparator_new ();
2355       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2356       gtk_widget_show (separator);
2357
2358       box2 = gtk_vbox_new (FALSE, 10);
2359       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2360       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2361       gtk_widget_show (box2);
2362
2363       button = gtk_button_new_with_label ("close");
2364       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2365                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2366                                  GTK_OBJECT (window));
2367       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2368       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2369       gtk_widget_grab_default (button);
2370       gtk_widget_show (button);
2371     }
2372
2373   if (!GTK_WIDGET_VISIBLE (window))
2374     gtk_widget_show (window);
2375   else
2376     gtk_widget_destroy (window);
2377 }
2378
2379 static void
2380 gtk_ifactory_cb (gpointer             callback_data,
2381                  guint                callback_action,
2382                  GtkWidget           *widget)
2383 {
2384   g_message ("ItemFactory: activated \"%s\"", gtk_item_factory_path_from_widget (widget));
2385 }
2386
2387 static GtkItemFactoryEntry menu_items[] =
2388 {
2389   { "/_File",            NULL,         0,                     0, "<Branch>" },
2390   { "/File/tearoff1",    NULL,         gtk_ifactory_cb,       0, "<Tearoff>" },
2391   { "/File/_New",        "<control>N", gtk_ifactory_cb,       0 },
2392   { "/File/_Open",       "<control>O", gtk_ifactory_cb,       0 },
2393   { "/File/_Save",       "<control>S", gtk_ifactory_cb,       0 },
2394   { "/File/Save _As...", NULL,         gtk_ifactory_cb,       0 },
2395   { "/File/sep1",        NULL,         gtk_ifactory_cb,       0, "<Separator>" },
2396   { "/File/_Quit",       "<control>Q", gtk_ifactory_cb,       0 },
2397
2398   { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
2399   { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
2400   { "/_Preferences/Color/_Red",         NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2401   { "/_Preferences/Color/_Green",       NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
2402   { "/_Preferences/Color/_Blue",        NULL, gtk_ifactory_cb, 0, "/Preferences/Color/Red" },
2403   { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
2404   { "/_Preferences/Shape/_Square",      NULL, gtk_ifactory_cb, 0, "<RadioItem>" },
2405   { "/_Preferences/Shape/_Rectangle",   NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Square" },
2406   { "/_Preferences/Shape/_Oval",        NULL, gtk_ifactory_cb, 0, "/Preferences/Shape/Rectangle" },
2407
2408   { "/_Help",            NULL,         0,                     0, "<LastBranch>" },
2409   { "/Help/_About",      NULL,         gtk_ifactory_cb,       0 },
2410 };
2411
2412 static int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
2413
2414 static void
2415 create_item_factory (void)
2416 {
2417   static GtkWidget *window = NULL;
2418   
2419   if (!window)
2420     {
2421       GtkWidget *box1;
2422       GtkWidget *box2;
2423       GtkWidget *separator;
2424       GtkWidget *label;
2425       GtkWidget *button;
2426       GtkAccelGroup *accel_group;
2427       GtkItemFactory *item_factory;
2428       
2429       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2430       
2431       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2432                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2433                           &window);
2434       gtk_signal_connect (GTK_OBJECT (window), "delete-event",
2435                           GTK_SIGNAL_FUNC (gtk_true),
2436                           NULL);
2437       
2438       accel_group = gtk_accel_group_new ();
2439       item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
2440       gtk_object_set_data_full (GTK_OBJECT (window),
2441                                 "<main>",
2442                                 item_factory,
2443                                 (GtkDestroyNotify) gtk_object_unref);
2444       gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
2445       gtk_window_set_title (GTK_WINDOW (window), "Item Factory");
2446       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2447       gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
2448
2449       /* preselect /Preferences/Shape/Oval over the other radios
2450        */
2451       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory,
2452                                                                                       "/Preferences/Shape/Oval")),
2453                                       TRUE);
2454
2455       box1 = gtk_vbox_new (FALSE, 0);
2456       gtk_container_add (GTK_CONTAINER (window), box1);
2457       
2458       gtk_box_pack_start (GTK_BOX (box1),
2459                           gtk_item_factory_get_widget (item_factory, "<main>"),
2460                           FALSE, FALSE, 0);
2461
2462       label = gtk_label_new ("Type\n<alt>\nto start");
2463       gtk_widget_set_usize (label, 200, 200);
2464       gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
2465       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
2466
2467
2468       separator = gtk_hseparator_new ();
2469       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2470
2471
2472       box2 = gtk_vbox_new (FALSE, 10);
2473       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2474       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2475
2476       button = gtk_button_new_with_label ("close");
2477       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2478                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2479                                  GTK_OBJECT (window));
2480       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2481       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2482       gtk_widget_grab_default (button);
2483
2484       gtk_widget_show_all (window);
2485     }
2486   else
2487     gtk_widget_destroy (window);
2488 }
2489
2490 /*
2491  * GtkScrolledWindow
2492  */
2493
2494 static void
2495 scrolled_windows_remove (GtkWidget *widget, GtkWidget *scrollwin)
2496 {
2497   static GtkWidget *parent = NULL;
2498   static GtkWidget *float_parent;
2499
2500   if (parent)
2501     {
2502       gtk_widget_reparent (scrollwin, parent);
2503       gtk_widget_destroy (float_parent);
2504       float_parent = NULL;
2505       parent = NULL;
2506     }
2507   else
2508     {
2509       parent = widget->parent;
2510       float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2511       gtk_widget_reparent (scrollwin, float_parent);
2512       gtk_widget_show (float_parent);
2513     }
2514 }
2515
2516 /*
2517  create_modal_window
2518  */
2519
2520 static gboolean
2521 cmw_destroy_cb(GtkWidget *widget)
2522 {
2523   /* This is needed to get out of gtk_main */
2524   gtk_main_quit ();
2525
2526   return FALSE;
2527 }
2528
2529 static void
2530 cmw_color (GtkWidget *widget, GtkWidget *parent)
2531 {
2532     GtkWidget *csd;
2533
2534     csd=gtk_color_selection_dialog_new ("This is a modal color selection dialog");
2535
2536     /* Set as modal */
2537     gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
2538
2539     /* And mark it as a transient dialog */
2540     gtk_window_set_transient_for (GTK_WINDOW (csd), GTK_WINDOW (parent));
2541     
2542     gtk_signal_connect (GTK_OBJECT(csd), "destroy",
2543                         GTK_SIGNAL_FUNC(cmw_destroy_cb),NULL);
2544
2545     gtk_signal_connect_object (GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(csd)->ok_button),
2546                                "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
2547                                GTK_OBJECT (csd));
2548     gtk_signal_connect_object (GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(csd)->cancel_button),
2549                                "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
2550                                GTK_OBJECT (csd));
2551     
2552     /* wait until destroy calls gtk_main_quit */
2553     gtk_widget_show (csd);    
2554     gtk_main ();
2555 }
2556
2557 static void
2558 cmw_file (GtkWidget *widget, GtkWidget *parent)
2559 {
2560     GtkWidget *fs;
2561
2562     fs = gtk_file_selection_new("This is a modal file selection dialog");
2563
2564     /* Set as modal */
2565     gtk_window_set_modal (GTK_WINDOW(fs),TRUE);
2566
2567     /* And mark it as a transient dialog */
2568     gtk_window_set_transient_for (GTK_WINDOW (fs), GTK_WINDOW (parent));
2569
2570     gtk_signal_connect (GTK_OBJECT(fs), "destroy",
2571                         GTK_SIGNAL_FUNC(cmw_destroy_cb),NULL);
2572
2573     gtk_signal_connect_object (GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
2574                                "clicked",GTK_SIGNAL_FUNC(gtk_widget_destroy),
2575                                GTK_OBJECT (fs));
2576     gtk_signal_connect_object (GTK_OBJECT(GTK_FILE_SELECTION(fs)->cancel_button),
2577                                "clicked",GTK_SIGNAL_FUNC(gtk_widget_destroy),
2578                                GTK_OBJECT (fs));
2579     
2580     /* wait until destroy calls gtk_main_quit */
2581     gtk_widget_show (fs);
2582     
2583     gtk_main();
2584 }
2585
2586
2587 static void
2588 create_modal_window (void)
2589 {
2590   GtkWidget *window = NULL;
2591   GtkWidget *box1,*box2;
2592   GtkWidget *frame1;
2593   GtkWidget *btnColor,*btnFile,*btnClose;
2594
2595   /* Create modal window (Here you can use any window descendent )*/
2596   window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
2597   gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
2598
2599   /* Set window as modal */
2600   gtk_window_set_modal (GTK_WINDOW(window),TRUE);
2601
2602   /* Create widgets */
2603   box1 = gtk_vbox_new (FALSE,5);
2604    frame1 = gtk_frame_new ("Standard dialogs in modal form");
2605     box2 = gtk_vbox_new (TRUE,5);
2606      btnColor = gtk_button_new_with_label ("Color");
2607      btnFile = gtk_button_new_with_label ("File Selection");
2608      btnClose = gtk_button_new_with_label ("Close");
2609
2610   /* Init widgets */
2611   gtk_container_set_border_width (GTK_CONTAINER(box1),3);
2612   gtk_container_set_border_width (GTK_CONTAINER(box2),3);
2613     
2614   /* Pack widgets */
2615   gtk_container_add (GTK_CONTAINER (window), box1);
2616    gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
2617     gtk_container_add (GTK_CONTAINER (frame1), box2);
2618      gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
2619      gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
2620    gtk_box_pack_start (GTK_BOX (box1), gtk_hseparator_new (), FALSE, FALSE, 4);
2621    gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
2622    
2623   /* connect signals */
2624   gtk_signal_connect_object (GTK_OBJECT (btnClose), "clicked",
2625                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
2626                              GTK_OBJECT (window));
2627
2628   gtk_signal_connect (GTK_OBJECT (window), "destroy",
2629                       GTK_SIGNAL_FUNC (cmw_destroy_cb),NULL);
2630   
2631   gtk_signal_connect (GTK_OBJECT (btnColor), "clicked",
2632                       GTK_SIGNAL_FUNC (cmw_color),window);
2633   gtk_signal_connect (GTK_OBJECT (btnFile), "clicked",
2634                       GTK_SIGNAL_FUNC (cmw_file),window);
2635
2636   /* Show widgets */
2637   gtk_widget_show_all (window);
2638
2639   /* wait until dialog get destroyed */
2640   gtk_main();
2641 }
2642
2643 /*
2644  * GtkScrolledWindow
2645  */
2646
2647 static void
2648 create_scrolled_windows (void)
2649 {
2650   static GtkWidget *window;
2651   GtkWidget *scrolled_window;
2652   GtkWidget *table;
2653   GtkWidget *button;
2654   char buffer[32];
2655   int i, j;
2656
2657   if (!window)
2658     {
2659       window = gtk_dialog_new ();
2660
2661       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2662                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2663                           &window);
2664
2665       gtk_window_set_title (GTK_WINDOW (window), "dialog");
2666       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2667
2668
2669       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
2670       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
2671       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
2672                                       GTK_POLICY_AUTOMATIC,
2673                                       GTK_POLICY_AUTOMATIC);
2674       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
2675                           scrolled_window, TRUE, TRUE, 0);
2676       gtk_widget_show (scrolled_window);
2677
2678       table = gtk_table_new (20, 20, FALSE);
2679       gtk_table_set_row_spacings (GTK_TABLE (table), 10);
2680       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
2681       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), table);
2682       gtk_container_set_focus_hadjustment (GTK_CONTAINER (table),
2683                                            gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
2684       gtk_container_set_focus_vadjustment (GTK_CONTAINER (table),
2685                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
2686       gtk_widget_show (table);
2687
2688       for (i = 0; i < 20; i++)
2689         for (j = 0; j < 20; j++)
2690           {
2691             sprintf (buffer, "button (%d,%d)\n", i, j);
2692             button = gtk_toggle_button_new_with_label (buffer);
2693             gtk_table_attach_defaults (GTK_TABLE (table), button,
2694                                        i, i+1, j, j+1);
2695             gtk_widget_show (button);
2696           }
2697
2698
2699       button = gtk_button_new_with_label ("close");
2700       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2701                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2702                                  GTK_OBJECT (window));
2703       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2704       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
2705                           button, TRUE, TRUE, 0);
2706       gtk_widget_grab_default (button);
2707       gtk_widget_show (button);
2708
2709       button = gtk_button_new_with_label ("remove");
2710       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2711                                  GTK_SIGNAL_FUNC(scrolled_windows_remove),
2712                                  GTK_OBJECT (scrolled_window));
2713       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2714       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
2715                           button, TRUE, TRUE, 0);
2716       gtk_widget_grab_default (button);
2717       gtk_widget_show (button);
2718
2719       gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
2720     }
2721
2722   if (!GTK_WIDGET_VISIBLE (window))
2723     gtk_widget_show (window);
2724   else
2725     gtk_widget_destroy (window);
2726 }
2727
2728 /*
2729  * GtkEntry
2730  */
2731
2732 static void
2733 entry_toggle_editable (GtkWidget *checkbutton,
2734                        GtkWidget *entry)
2735 {
2736    gtk_entry_set_editable(GTK_ENTRY(entry),
2737                           GTK_TOGGLE_BUTTON(checkbutton)->active);
2738 }
2739
2740 static void
2741 entry_toggle_sensitive (GtkWidget *checkbutton,
2742                         GtkWidget *entry)
2743 {
2744    gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
2745 }
2746
2747 static void
2748 entry_toggle_visibility (GtkWidget *checkbutton,
2749                         GtkWidget *entry)
2750 {
2751    gtk_entry_set_visibility(GTK_ENTRY(entry),
2752                          GTK_TOGGLE_BUTTON(checkbutton)->active);
2753 }
2754
2755 static void
2756 create_entry (void)
2757 {
2758   static GtkWidget *window = NULL;
2759   GtkWidget *box1;
2760   GtkWidget *box2;
2761   GtkWidget *editable_check;
2762   GtkWidget *sensitive_check;
2763   GtkWidget *entry, *cb;
2764   GtkWidget *button;
2765   GtkWidget *separator;
2766   GList *cbitems = NULL;
2767
2768   if (!window)
2769     {
2770       cbitems = g_list_append(cbitems, "item0");
2771       cbitems = g_list_append(cbitems, "item1 item1");
2772       cbitems = g_list_append(cbitems, "item2 item2 item2");
2773       cbitems = g_list_append(cbitems, "item3 item3 item3 item3");
2774       cbitems = g_list_append(cbitems, "item4 item4 item4 item4 item4");
2775       cbitems = g_list_append(cbitems, "item5 item5 item5 item5 item5 item5");
2776       cbitems = g_list_append(cbitems, "item6 item6 item6 item6 item6");
2777       cbitems = g_list_append(cbitems, "item7 item7 item7 item7");
2778       cbitems = g_list_append(cbitems, "item8 item8 item8");
2779       cbitems = g_list_append(cbitems, "item9 item9");
2780
2781       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2782
2783       gtk_signal_connect (GTK_OBJECT (window), "destroy",
2784                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
2785                           &window);
2786
2787       gtk_window_set_title (GTK_WINDOW (window), "entry");
2788       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2789
2790
2791       box1 = gtk_vbox_new (FALSE, 0);
2792       gtk_container_add (GTK_CONTAINER (window), box1);
2793       gtk_widget_show (box1);
2794
2795
2796       box2 = gtk_vbox_new (FALSE, 10);
2797       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2798       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2799       gtk_widget_show (box2);
2800
2801       entry = gtk_entry_new ();
2802       gtk_entry_set_text (GTK_ENTRY (entry), "hello world");
2803       gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
2804       gtk_box_pack_start (GTK_BOX (box2), entry, TRUE, TRUE, 0);
2805       gtk_widget_show (entry);
2806
2807       cb = gtk_combo_new ();
2808       gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
2809       gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(cb)->entry), "hello world");
2810       gtk_editable_select_region (GTK_EDITABLE (GTK_COMBO(cb)->entry),
2811                                   0, -1);
2812       gtk_box_pack_start (GTK_BOX (box2), cb, TRUE, TRUE, 0);
2813       gtk_widget_show (cb);
2814
2815       editable_check = gtk_check_button_new_with_label("Editable");
2816       gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
2817       gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
2818                           GTK_SIGNAL_FUNC(entry_toggle_editable), entry);
2819       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE);
2820       gtk_widget_show (editable_check);
2821
2822       editable_check = gtk_check_button_new_with_label("Visible");
2823       gtk_box_pack_start (GTK_BOX (box2), editable_check, FALSE, TRUE, 0);
2824       gtk_signal_connect (GTK_OBJECT(editable_check), "toggled",
2825                           GTK_SIGNAL_FUNC(entry_toggle_visibility), entry);
2826       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(editable_check), TRUE);
2827       gtk_widget_show (editable_check);
2828
2829       sensitive_check = gtk_check_button_new_with_label("Sensitive");
2830       gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
2831       gtk_signal_connect (GTK_OBJECT(sensitive_check), "toggled",
2832                           GTK_SIGNAL_FUNC(entry_toggle_sensitive), entry);
2833       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sensitive_check), TRUE);
2834       gtk_widget_show (sensitive_check);
2835
2836       separator = gtk_hseparator_new ();
2837       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2838       gtk_widget_show (separator);
2839
2840
2841       box2 = gtk_vbox_new (FALSE, 10);
2842       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2843       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2844       gtk_widget_show (box2);
2845
2846
2847       button = gtk_button_new_with_label ("close");
2848       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
2849                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
2850                                  GTK_OBJECT (window));
2851       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2852       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
2853       gtk_widget_grab_default (button);
2854       gtk_widget_show (button);
2855     }
2856
2857   if (!GTK_WIDGET_VISIBLE (window))
2858     gtk_widget_show (window);
2859   else
2860     gtk_widget_destroy (window);
2861 }
2862
2863 /*
2864  * GtkSpinButton
2865  */
2866
2867 static GtkWidget *spinner1;
2868
2869 static void
2870 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
2871 {
2872   gtk_spin_button_set_snap_to_ticks (spin, GTK_TOGGLE_BUTTON (widget)->active);
2873 }
2874
2875 static void
2876 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
2877 {
2878   gtk_spin_button_set_numeric (spin, GTK_TOGGLE_BUTTON (widget)->active);
2879 }
2880
2881 static void
2882 change_digits (GtkWidget *widget, GtkSpinButton *spin)
2883 {
2884   gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
2885                               gtk_spin_button_get_value_as_int (spin));
2886 }
2887
2888 static void
2889 get_value (GtkWidget *widget, gpointer data)
2890 {
2891   gchar buf[32];
2892   GtkLabel *label;
2893   GtkSpinButton *spin;
2894
2895   spin = GTK_SPIN_BUTTON (spinner1);
2896   label = GTK_LABEL (gtk_object_get_user_data (GTK_OBJECT (widget)));
2897   if (GPOINTER_TO_INT (data) == 1)
2898     sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
2899   else
2900     sprintf (buf, "%0.*f", spin->digits,
2901              gtk_spin_button_get_value_as_float (spin));
2902   gtk_label_set_text (label, buf);
2903 }
2904
2905 static gint
2906 spin_button_time_output_func (GtkSpinButton *spin_button)
2907 {
2908   static gchar buf[6];
2909   gfloat hours;
2910   gfloat minutes;
2911
2912   hours = spin_button->adjustment->value / 60.0;
2913   minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
2914   sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
2915   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
2916     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
2917   return TRUE;
2918 }
2919
2920 static gint
2921 spin_button_month_input_func (GtkSpinButton *spin_button,
2922                               gfloat        *new_val)
2923 {
2924   gint i;
2925   static gchar *month[12] = { "January", "February", "March", "April",
2926                               "May", "June", "July", "August",
2927                               "September", "October", "November", "December" };
2928   gchar *tmp1, *tmp2;
2929   gboolean found = FALSE;
2930
2931   for (i = 1; i <= 12; i++)
2932     {
2933       tmp1 = g_strdup (month[i-1]);
2934       g_strup (tmp1);
2935       tmp2 = g_strdup (gtk_entry_get_text (GTK_ENTRY (spin_button)));
2936       g_strup (tmp2);
2937       if (strstr (tmp1, tmp2) == tmp1)
2938         found = TRUE;
2939       g_free (tmp1);
2940       g_free (tmp2);
2941       if (found)
2942         break;
2943     }
2944   if (!found)
2945     {
2946       *new_val = 0.0;
2947       return INPUT_ERROR;
2948     }
2949   *new_val = (gfloat) i;
2950   return TRUE;
2951 }
2952
2953 static gint
2954 spin_button_month_output_func (GtkSpinButton *spin_button)
2955 {
2956   gint i;
2957   static gchar *month[12] = { "January", "February", "March", "April",
2958                               "May", "June", "July", "August", "September",
2959                               "October", "November", "December" };
2960
2961   for (i = 1; i <= 12; i++)
2962     if (fabs (spin_button->adjustment->value - (double)i) < 1e-5)
2963       {
2964         if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
2965           gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
2966       }
2967   return TRUE;
2968 }
2969
2970 static gint
2971 spin_button_hex_input_func (GtkSpinButton *spin_button,
2972                             gfloat        *new_val)
2973 {
2974   gchar *buf;
2975   gchar *err;
2976   gfloat res;
2977
2978   buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
2979   res = (gfloat)(strtol(buf, &err, 16));
2980   *new_val = res;
2981   if (*err)
2982     return INPUT_ERROR;
2983   else
2984     return TRUE;
2985 }
2986
2987 static gint
2988 spin_button_hex_output_func (GtkSpinButton *spin_button)
2989 {
2990   static gchar buf[7];
2991   gint val;
2992
2993   val = (gint) spin_button->adjustment->value;
2994   if (fabs (val) < 1e-5)
2995     sprintf (buf, "0x00");
2996   else
2997     sprintf (buf, "0x%.2X", val);
2998   if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
2999     gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
3000   return TRUE;
3001 }
3002
3003 static void
3004 create_spins (void)
3005 {
3006   static GtkWidget *window = NULL;
3007   GtkWidget *frame;
3008   GtkWidget *hbox;
3009   GtkWidget *main_vbox;
3010   GtkWidget *vbox;
3011   GtkWidget *vbox2;
3012   GtkWidget *spinner2;
3013   GtkWidget *spinner;
3014   GtkWidget *button;
3015   GtkWidget *label;
3016   GtkWidget *val_label;
3017   GtkAdjustment *adj;
3018
3019   if (!window)
3020     {
3021       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3022       
3023       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3024                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
3025                           &window);
3026       
3027       gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
3028       
3029       main_vbox = gtk_vbox_new (FALSE, 5);
3030       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
3031       gtk_container_add (GTK_CONTAINER (window), main_vbox);
3032       
3033       frame = gtk_frame_new ("Not accelerated");
3034       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
3035       
3036       vbox = gtk_vbox_new (FALSE, 0);
3037       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
3038       gtk_container_add (GTK_CONTAINER (frame), vbox);
3039       
3040       /* Time, month, hex spinners */
3041       
3042       hbox = gtk_hbox_new (FALSE, 0);
3043       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
3044       
3045       vbox2 = gtk_vbox_new (FALSE, 0);
3046       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
3047       
3048       label = gtk_label_new ("Time :");
3049       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3050       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
3051       
3052       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
3053       spinner = gtk_spin_button_new (adj, 0, 0);
3054       gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
3055       gtk_signal_connect (GTK_OBJECT (spinner),
3056                           "output",
3057                           GTK_SIGNAL_FUNC (spin_button_time_output_func),
3058                           NULL);
3059       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
3060       gtk_widget_set_usize (spinner, 55, -1);
3061       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
3062
3063       vbox2 = gtk_vbox_new (FALSE, 0);
3064       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
3065       
3066       label = gtk_label_new ("Month :");
3067       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3068       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
3069       
3070       adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
3071                                                   5.0, 0.0);
3072       spinner = gtk_spin_button_new (adj, 0, 0);
3073       gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
3074                                          GTK_UPDATE_IF_VALID);
3075       gtk_signal_connect (GTK_OBJECT (spinner),
3076                           "input",
3077                           GTK_SIGNAL_FUNC (spin_button_month_input_func),
3078                           NULL);
3079       gtk_signal_connect (GTK_OBJECT (spinner),
3080                           "output",
3081                           GTK_SIGNAL_FUNC (spin_button_month_output_func),
3082                           NULL);
3083       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
3084       gtk_widget_set_usize (spinner, 85, -1);
3085       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
3086       
3087       vbox2 = gtk_vbox_new (FALSE, 0);
3088       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
3089
3090       label = gtk_label_new ("Hex :");
3091       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3092       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
3093
3094       adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 255, 1, 16, 0);
3095       spinner = gtk_spin_button_new (adj, 0, 0);
3096       gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
3097       gtk_signal_connect (GTK_OBJECT (spinner),
3098                           "input",
3099                           GTK_SIGNAL_FUNC (spin_button_hex_input_func),
3100                           NULL);
3101       gtk_signal_connect (GTK_OBJECT (spinner),
3102                           "output",
3103                           GTK_SIGNAL_FUNC (spin_button_hex_output_func),
3104                           NULL);
3105       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
3106       gtk_widget_set_usize (spinner, 55, 0);
3107       gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
3108
3109       frame = gtk_frame_new ("Accelerated");
3110       gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
3111   
3112       vbox = gtk_vbox_new (FALSE, 0);
3113       gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
3114       gtk_container_add (GTK_CONTAINER (frame), vbox);
3115       
3116       hbox = gtk_hbox_new (FALSE, 0);
3117       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
3118       
3119       vbox2 = gtk_vbox_new (FALSE, 0);
3120       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
3121       
3122       label = gtk_label_new ("Value :");
3123       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3124       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
3125
3126       adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,
3127                                                   0.5, 100.0, 0.0);
3128       spinner1 = gtk_spin_button_new (adj, 1.0, 2);
3129       gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
3130       gtk_widget_set_usize (spinner1, 100, 0);
3131       gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
3132
3133       vbox2 = gtk_vbox_new (FALSE, 0);
3134       gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
3135
3136       label = gtk_label_new ("Digits :");
3137       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3138       gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
3139
3140       adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 5, 1, 1, 0);
3141       spinner2 = gtk_spin_button_new (adj, 0.0, 0);
3142       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
3143                           GTK_SIGNAL_FUNC (change_digits),
3144                           (gpointer) spinner2);
3145       gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
3146
3147       hbox = gtk_hbox_new (FALSE, 0);
3148       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
3149
3150       button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
3151       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3152                           GTK_SIGNAL_FUNC (toggle_snap),
3153                           spinner1);
3154       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
3155       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3156
3157       button = gtk_check_button_new_with_label ("Numeric only input mode");
3158       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3159                           GTK_SIGNAL_FUNC (toggle_numeric),
3160                           spinner1);
3161       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
3162       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3163
3164       val_label = gtk_label_new ("");
3165
3166       hbox = gtk_hbox_new (FALSE, 0);
3167       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
3168
3169       button = gtk_button_new_with_label ("Value as Int");
3170       gtk_object_set_user_data (GTK_OBJECT (button), val_label);
3171       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3172                           GTK_SIGNAL_FUNC (get_value),
3173                           GINT_TO_POINTER (1));
3174       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3175
3176       button = gtk_button_new_with_label ("Value as Float");
3177       gtk_object_set_user_data (GTK_OBJECT (button), val_label);
3178       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3179                           GTK_SIGNAL_FUNC (get_value),
3180                           GINT_TO_POINTER (2));
3181       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3182
3183       gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
3184       gtk_label_set_text (GTK_LABEL (val_label), "0");
3185
3186       hbox = gtk_hbox_new (FALSE, 0);
3187       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
3188   
3189       button = gtk_button_new_with_label ("Close");
3190       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3191                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
3192                                  GTK_OBJECT (window));
3193       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3194     }
3195
3196   if (!GTK_WIDGET_VISIBLE (window))
3197     gtk_widget_show_all (window);
3198   else
3199     gtk_widget_destroy (window);
3200 }
3201
3202
3203 /*
3204  * Cursors
3205  */
3206
3207 static gint
3208 cursor_expose_event (GtkWidget *widget,
3209                      GdkEvent  *event,
3210                      gpointer   user_data)
3211 {
3212   GtkDrawingArea *darea;
3213   GdkDrawable *drawable;
3214   GdkGC *black_gc;
3215   GdkGC *gray_gc;
3216   GdkGC *white_gc;
3217   guint max_width;
3218   guint max_height;
3219
3220   g_return_val_if_fail (widget != NULL, TRUE);
3221   g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), TRUE);
3222
3223   darea = GTK_DRAWING_AREA (widget);
3224   drawable = widget->window;
3225   white_gc = widget->style->white_gc;
3226   gray_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
3227   black_gc = widget->style->black_gc;
3228   max_width = widget->allocation.width;
3229   max_height = widget->allocation.height;
3230
3231   gdk_draw_rectangle (drawable, white_gc,
3232                       TRUE,
3233                       0,
3234                       0,
3235                       max_width,
3236                       max_height / 2);
3237
3238   gdk_draw_rectangle (drawable, black_gc,
3239                       TRUE,
3240                       0,
3241                       max_height / 2,
3242                       max_width,
3243                       max_height / 2);
3244
3245   gdk_draw_rectangle (drawable, gray_gc,
3246                       TRUE,
3247                       max_width / 3,
3248                       max_height / 3,
3249                       max_width / 3,
3250                       max_height / 3);
3251
3252   return TRUE;
3253 }
3254
3255 static void
3256 set_cursor (GtkWidget *spinner,
3257             GtkWidget *widget)
3258 {
3259   guint c;
3260   GdkCursor *cursor;
3261   GtkWidget *label;
3262   GtkFlagValue *vals;
3263
3264   c = CLAMP (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)), 0, 152);
3265   c &= 0xfe;
3266
3267   label = gtk_object_get_user_data (GTK_OBJECT (spinner));
3268   vals = gtk_type_enum_get_values (GTK_TYPE_GDK_CURSOR_TYPE);
3269   while (vals && vals->value != c)
3270     vals++;
3271   if (vals)
3272     gtk_label_set_text (GTK_LABEL (label), vals->value_nick);
3273   else
3274     gtk_label_set_text (GTK_LABEL (label), "<unknown>");
3275
3276   cursor = gdk_cursor_new (c);
3277   gdk_window_set_cursor (widget->window, cursor);
3278   gdk_cursor_unref (cursor);
3279 }
3280
3281 static gint
3282 cursor_event (GtkWidget          *widget,
3283               GdkEvent           *event,
3284               GtkSpinButton      *spinner)
3285 {
3286   if ((event->type == GDK_BUTTON_PRESS) &&
3287       ((event->button.button == 1) ||
3288        (event->button.button == 3)))
3289     {
3290       gtk_spin_button_spin (spinner, event->button.button == 1 ?
3291                             GTK_SPIN_STEP_FORWARD : GTK_SPIN_STEP_BACKWARD, 0);
3292       return TRUE;
3293     }
3294
3295   return FALSE;
3296 }
3297
3298 static void
3299 create_cursors (void)
3300 {
3301   static GtkWidget *window = NULL;
3302   GtkWidget *frame;
3303   GtkWidget *hbox;
3304   GtkWidget *main_vbox;
3305   GtkWidget *vbox;
3306   GtkWidget *darea;
3307   GtkWidget *spinner;
3308   GtkWidget *button;
3309   GtkWidget *label;
3310   GtkWidget *any;
3311   GtkAdjustment *adj;
3312
3313   if (!window)
3314     {
3315       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3316       
3317       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3318                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
3319                           &window);
3320       
3321       gtk_window_set_title (GTK_WINDOW (window), "Cursors");
3322       
3323       main_vbox = gtk_vbox_new (FALSE, 5);
3324       gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
3325       gtk_container_add (GTK_CONTAINER (window), main_vbox);
3326
3327       vbox =
3328         gtk_widget_new (gtk_vbox_get_type (),
3329                         "GtkBox::homogeneous", FALSE,
3330                         "GtkBox::spacing", 5,
3331                         "GtkContainer::border_width", 10,
3332                         "GtkWidget::parent", main_vbox,
3333                         "GtkWidget::visible", TRUE,
3334                         NULL);
3335
3336       hbox = gtk_hbox_new (FALSE, 0);
3337       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3338       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3339       
3340       label = gtk_label_new ("Cursor Value : ");
3341       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
3342       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3343       
3344       adj = (GtkAdjustment *) gtk_adjustment_new (0,
3345                                                   0, 152,
3346                                                   2,
3347                                                   10, 0);
3348       spinner = gtk_spin_button_new (adj, 0, 0);
3349       gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0);
3350
3351       frame =
3352         gtk_widget_new (gtk_frame_get_type (),
3353                         "GtkFrame::shadow", GTK_SHADOW_ETCHED_IN,
3354                         "GtkFrame::label_xalign", 0.5,
3355                         "GtkFrame::label", "Cursor Area",
3356                         "GtkContainer::border_width", 10,
3357                         "GtkWidget::parent", vbox,
3358                         "GtkWidget::visible", TRUE,
3359                         NULL);
3360
3361       darea = gtk_drawing_area_new ();
3362       gtk_widget_set_usize (darea, 80, 80);
3363       gtk_container_add (GTK_CONTAINER (frame), darea);
3364       gtk_signal_connect (GTK_OBJECT (darea),
3365                           "expose_event",
3366                           GTK_SIGNAL_FUNC (cursor_expose_event),
3367                           NULL);
3368       gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
3369       gtk_signal_connect (GTK_OBJECT (darea),
3370                           "button_press_event",
3371                           GTK_SIGNAL_FUNC (cursor_event),
3372                           spinner);
3373       gtk_widget_show (darea);
3374
3375       gtk_signal_connect (GTK_OBJECT (spinner), "changed",
3376                           GTK_SIGNAL_FUNC (set_cursor),
3377                           darea);
3378
3379       label = gtk_widget_new (GTK_TYPE_LABEL,
3380                               "visible", TRUE,
3381                               "label", "XXX",
3382                               "parent", vbox,
3383                               NULL);
3384       gtk_container_child_set (GTK_CONTAINER (vbox), label,
3385                                "expand", FALSE,
3386                                NULL);
3387       gtk_object_set_user_data (GTK_OBJECT (spinner), label);
3388
3389       any =
3390         gtk_widget_new (gtk_hseparator_get_type (),
3391                         "GtkWidget::visible", TRUE,
3392                         NULL);
3393       gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
3394   
3395       hbox = gtk_hbox_new (FALSE, 0);
3396       gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
3397       gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
3398
3399       button = gtk_button_new_with_label ("Close");
3400       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3401                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
3402                                  GTK_OBJECT (window));
3403       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
3404
3405       gtk_widget_show_all (window);
3406
3407       set_cursor (spinner, darea);
3408     }
3409   else
3410     gtk_widget_destroy (window);
3411 }
3412
3413 /*
3414  * GtkList
3415  */
3416
3417 static void
3418 list_add (GtkWidget *widget,
3419           GtkWidget *list)
3420 {
3421   static int i = 1;
3422   gchar buffer[64];
3423   GtkWidget *list_item;
3424   GtkContainer *container;
3425
3426   container = GTK_CONTAINER (list);
3427
3428   sprintf (buffer, "added item %d", i++);
3429   list_item = gtk_list_item_new_with_label (buffer);
3430   gtk_widget_show (list_item);
3431
3432   gtk_container_add (container, list_item);
3433 }
3434
3435 static void
3436 list_remove (GtkWidget *widget,
3437              GtkList   *list)
3438 {
3439   GList *clear_list = NULL;
3440   GList *sel_row = NULL;
3441   GList *work = NULL;
3442
3443   if (list->selection_mode == GTK_SELECTION_EXTENDED)
3444     {
3445       GtkWidget *item;
3446
3447       item = GTK_CONTAINER (list)->focus_child;
3448       if (!item && list->selection)
3449         item = list->selection->data;
3450
3451       if (item)
3452         {
3453           work = g_list_find (list->children, item);
3454           for (sel_row = work; sel_row; sel_row = sel_row->next)
3455             if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
3456               break;
3457
3458           if (!sel_row)
3459             {
3460               for (sel_row = work; sel_row; sel_row = sel_row->prev)
3461                 if (GTK_WIDGET (sel_row->data)->state != GTK_STATE_SELECTED)
3462                   break;
3463             }
3464         }
3465     }
3466
3467   for (work = list->selection; work; work = work->next)
3468     clear_list = g_list_prepend (clear_list, work->data);
3469
3470   clear_list = g_list_reverse (clear_list);
3471   gtk_list_remove_items (GTK_LIST (list), clear_list);
3472   g_list_free (clear_list);
3473
3474   if (list->selection_mode == GTK_SELECTION_EXTENDED && sel_row)
3475     gtk_list_select_child (list, GTK_WIDGET(sel_row->data));
3476 }
3477
3478 static void
3479 list_clear (GtkWidget *widget,
3480             GtkWidget *list)
3481 {
3482   gtk_list_clear_items (GTK_LIST (list), 0, -1);
3483 }
3484
3485 #define RADIOMENUTOGGLED(_rmi_, __i) { \
3486   GSList * __g; \
3487   __i = 0; \
3488   __g = gtk_radio_menu_item_group(_rmi_); \
3489   while( __g  && !((GtkCheckMenuItem *)(__g->data))->active) { \
3490     __g = __g->next; \
3491     __i++; \
3492   }\
3493 }
3494
3495 static GtkWidget *list_omenu;
3496
3497 static void 
3498 list_toggle_sel_mode (GtkWidget *widget, GtkList *list)
3499 {
3500   gint i;
3501
3502   if (!GTK_WIDGET_MAPPED (widget))
3503     return;
3504
3505   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3506                     (((GtkOptionMenu *)list_omenu)->menu_item), i);
3507
3508   gtk_list_set_selection_mode (list, (GtkSelectionMode) (3-i));
3509 }
3510
3511 static void
3512 create_list (void)
3513 {
3514   static GtkWidget *window = NULL;
3515
3516   static OptionMenuItem items[] =
3517   {
3518     { "Single",   list_toggle_sel_mode },
3519     { "Browse",   list_toggle_sel_mode },
3520     { "Multiple", list_toggle_sel_mode },
3521     { "Extended", list_toggle_sel_mode }
3522   };
3523
3524   if (!window)
3525     {
3526       GtkWidget *cbox;
3527       GtkWidget *vbox;
3528       GtkWidget *hbox;
3529       GtkWidget *label;
3530       GtkWidget *scrolled_win;
3531       GtkWidget *list;
3532       GtkWidget *button;
3533       GtkWidget *separator;
3534       FILE *infile;
3535
3536       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3537
3538       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3539                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
3540                           &window);
3541
3542       gtk_window_set_title (GTK_WINDOW (window), "list");
3543       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3544
3545       vbox = gtk_vbox_new (FALSE, 0);
3546       gtk_container_add (GTK_CONTAINER (window), vbox);
3547
3548       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
3549       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
3550       gtk_widget_set_usize (scrolled_win, -1, 300);
3551       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
3552       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
3553                                       GTK_POLICY_AUTOMATIC,
3554                                       GTK_POLICY_AUTOMATIC);
3555
3556       list = gtk_list_new ();
3557       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_EXTENDED);
3558       gtk_scrolled_window_add_with_viewport
3559         (GTK_SCROLLED_WINDOW (scrolled_win), list);
3560       gtk_container_set_focus_vadjustment
3561         (GTK_CONTAINER (list),
3562          gtk_scrolled_window_get_vadjustment
3563          (GTK_SCROLLED_WINDOW (scrolled_win)));
3564       gtk_container_set_focus_hadjustment
3565         (GTK_CONTAINER (list),
3566          gtk_scrolled_window_get_hadjustment
3567          (GTK_SCROLLED_WINDOW (scrolled_win)));
3568
3569       if ((infile = fopen("gtkenums.h", "r")))
3570         {
3571           char buffer[256];
3572           char *pos;
3573           GtkWidget *item;
3574
3575           while (fgets (buffer, 256, infile))
3576             {
3577               if ((pos = strchr (buffer, '\n')))
3578                 *pos = 0;
3579               item = gtk_list_item_new_with_label (buffer);
3580               gtk_container_add (GTK_CONTAINER (list), item);
3581             }
3582           
3583           fclose (infile);
3584         }
3585
3586
3587       hbox = gtk_hbox_new (TRUE, 5);
3588       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3589       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
3590
3591       button = gtk_button_new_with_label ("Insert Row");
3592       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3593       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3594                           GTK_SIGNAL_FUNC (list_add),
3595                           list);
3596
3597       button = gtk_button_new_with_label ("Clear List");
3598       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3599       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3600                           GTK_SIGNAL_FUNC (list_clear),
3601                           list);
3602
3603       button = gtk_button_new_with_label ("Remove Selection");
3604       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
3605       gtk_signal_connect (GTK_OBJECT (button), "clicked",
3606                           GTK_SIGNAL_FUNC (list_remove),
3607                           list);
3608
3609       cbox = gtk_hbox_new (FALSE, 0);
3610       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
3611
3612       hbox = gtk_hbox_new (FALSE, 5);
3613       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
3614       gtk_box_pack_start (GTK_BOX (cbox), hbox, TRUE, FALSE, 0);
3615
3616       label = gtk_label_new ("Selection Mode :");
3617       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
3618
3619       list_omenu = build_option_menu (items, 4, 3, list);
3620       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
3621
3622       separator = gtk_hseparator_new ();
3623       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
3624
3625       cbox = gtk_hbox_new (FALSE, 0);
3626       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
3627
3628       button = gtk_button_new_with_label ("close");
3629       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
3630       gtk_box_pack_start (GTK_BOX (cbox), button, TRUE, TRUE, 0);
3631       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3632                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
3633                                  GTK_OBJECT (window));
3634
3635       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3636       gtk_widget_grab_default (button);
3637     }
3638
3639   if (!GTK_WIDGET_VISIBLE (window))
3640     gtk_widget_show_all (window);
3641   else
3642     gtk_widget_destroy (window);
3643 }
3644
3645 /*
3646  * GtkCList
3647  */
3648
3649 static char * book_open_xpm[] = {
3650 "16 16 4 1",
3651 "       c None s None",
3652 ".      c black",
3653 "X      c #808080",
3654 "o      c white",
3655 "                ",
3656 "  ..            ",
3657 " .Xo.    ...    ",
3658 " .Xoo. ..oo.    ",
3659 " .Xooo.Xooo...  ",
3660 " .Xooo.oooo.X.  ",
3661 " .Xooo.Xooo.X.  ",
3662 " .Xooo.oooo.X.  ",
3663 " .Xooo.Xooo.X.  ",
3664 " .Xooo.oooo.X.  ",
3665 "  .Xoo.Xoo..X.  ",
3666 "   .Xo.o..ooX.  ",
3667 "    .X..XXXXX.  ",
3668 "    ..X.......  ",
3669 "     ..         ",
3670 "                "};
3671
3672 static char * book_closed_xpm[] = {
3673 "16 16 6 1",
3674 "       c None s None",
3675 ".      c black",
3676 "X      c red",
3677 "o      c yellow",
3678 "O      c #808080",
3679 "#      c white",
3680 "                ",
3681 "       ..       ",
3682 "     ..XX.      ",
3683 "   ..XXXXX.     ",
3684 " ..XXXXXXXX.    ",
3685 ".ooXXXXXXXXX.   ",
3686 "..ooXXXXXXXXX.  ",
3687 ".X.ooXXXXXXXXX. ",
3688 ".XX.ooXXXXXX..  ",
3689 " .XX.ooXXX..#O  ",
3690 "  .XX.oo..##OO. ",
3691 "   .XX..##OO..  ",
3692 "    .X.#OO..    ",
3693 "     ..O..      ",
3694 "      ..        ",
3695 "                "};
3696
3697 static char * mini_page_xpm[] = {
3698 "16 16 4 1",
3699 "       c None s None",
3700 ".      c black",
3701 "X      c white",
3702 "o      c #808080",
3703 "                ",
3704 "   .......      ",
3705 "   .XXXXX..     ",
3706 "   .XoooX.X.    ",
3707 "   .XXXXX....   ",
3708 "   .XooooXoo.o  ",
3709 "   .XXXXXXXX.o  ",
3710 "   .XooooooX.o  ",
3711 "   .XXXXXXXX.o  ",
3712 "   .XooooooX.o  ",
3713 "   .XXXXXXXX.o  ",
3714 "   .XooooooX.o  ",
3715 "   .XXXXXXXX.o  ",
3716 "   ..........o  ",
3717 "    oooooooooo  ",
3718 "                "};
3719
3720 static char * gtk_mini_xpm[] = {
3721 "15 20 17 1",
3722 "       c None",
3723 ".      c #14121F",
3724 "+      c #278828",
3725 "@      c #9B3334",
3726 "#      c #284C72",
3727 "$      c #24692A",
3728 "%      c #69282E",
3729 "&      c #37C539",
3730 "*      c #1D2F4D",
3731 "=      c #6D7076",
3732 "-      c #7D8482",
3733 ";      c #E24A49",
3734 ">      c #515357",
3735 ",      c #9B9C9B",
3736 "'      c #2FA232",
3737 ")      c #3CE23D",
3738 "!      c #3B6CCB",
3739 "               ",
3740 "      ***>     ",
3741 "    >.*!!!*    ",
3742 "   ***....#*=  ",
3743 "  *!*.!!!**!!# ",
3744 " .!!#*!#*!!!!# ",
3745 " @%#!.##.*!!$& ",
3746 " @;%*!*.#!#')) ",
3747 " @;;@%!!*$&)'' ",
3748 " @%.%@%$'&)$+' ",
3749 " @;...@$'*'*)+ ",
3750 " @;%..@$+*.')$ ",
3751 " @;%%;;$+..$)# ",
3752 " @;%%;@$$$'.$# ",
3753 " %;@@;;$$+))&* ",
3754 "  %;;;@+$&)&*  ",
3755 "   %;;@'))+>   ",
3756 "    %;@'&#     ",
3757 "     >%$$      ",
3758 "      >=       "};
3759
3760 #define TESTGTK_CLIST_COLUMNS 12
3761 static gint clist_rows = 0;
3762 static GtkWidget *clist_omenu;
3763
3764 static void
3765 add1000_clist (GtkWidget *widget, gpointer data)
3766 {
3767   gint i, row;
3768   char text[TESTGTK_CLIST_COLUMNS][50];
3769   char *texts[TESTGTK_CLIST_COLUMNS];
3770   GdkBitmap *mask;
3771   GdkPixmap *pixmap;
3772   GtkCList  *clist;
3773
3774   clist = GTK_CLIST (data);
3775
3776   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
3777                                          &mask, 
3778                                          &GTK_WIDGET (data)->style->white,
3779                                          gtk_mini_xpm);
3780
3781   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3782     {
3783       texts[i] = text[i];
3784       sprintf (text[i], "Column %d", i);
3785     }
3786   
3787   texts[3] = NULL;
3788   sprintf (text[1], "Right");
3789   sprintf (text[2], "Center");
3790   
3791   gtk_clist_freeze (GTK_CLIST (data));
3792   for (i = 0; i < 1000; i++)
3793     {
3794       sprintf (text[0], "CListRow %d", rand() % 10000);
3795       row = gtk_clist_append (clist, texts);
3796       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
3797     }
3798
3799   gtk_clist_thaw (GTK_CLIST (data));
3800
3801   gdk_pixmap_unref (pixmap);
3802   gdk_bitmap_unref (mask);
3803 }
3804
3805 static void
3806 add10000_clist (GtkWidget *widget, gpointer data)
3807 {
3808   gint i;
3809   char text[TESTGTK_CLIST_COLUMNS][50];
3810   char *texts[TESTGTK_CLIST_COLUMNS];
3811
3812   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3813     {
3814       texts[i] = text[i];
3815       sprintf (text[i], "Column %d", i);
3816     }
3817   
3818   sprintf (text[1], "Right");
3819   sprintf (text[2], "Center");
3820   
3821   gtk_clist_freeze (GTK_CLIST (data));
3822   for (i = 0; i < 10000; i++)
3823     {
3824       sprintf (text[0], "CListRow %d", rand() % 10000);
3825       gtk_clist_append (GTK_CLIST (data), texts);
3826     }
3827   gtk_clist_thaw (GTK_CLIST (data));
3828 }
3829
3830 void
3831 clear_clist (GtkWidget *widget, gpointer data)
3832 {
3833   gtk_clist_clear (GTK_CLIST (data));
3834   clist_rows = 0;
3835 }
3836
3837 void clist_remove_selection (GtkWidget *widget, GtkCList *clist)
3838 {
3839   gtk_clist_freeze (clist);
3840
3841   while (clist->selection)
3842     {
3843       gint row;
3844
3845       clist_rows--;
3846       row = GPOINTER_TO_INT (clist->selection->data);
3847
3848       gtk_clist_remove (clist, row);
3849
3850       if (clist->selection_mode == GTK_SELECTION_BROWSE)
3851         break;
3852     }
3853
3854   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
3855       clist->focus_row >= 0)
3856     gtk_clist_select_row (clist, clist->focus_row, -1);
3857
3858   gtk_clist_thaw (clist);
3859 }
3860
3861 void toggle_title_buttons (GtkWidget *widget, GtkCList *clist)
3862 {
3863   if (GTK_TOGGLE_BUTTON (widget)->active)
3864     gtk_clist_column_titles_show (clist);
3865   else
3866     gtk_clist_column_titles_hide (clist);
3867 }
3868
3869 void toggle_reorderable (GtkWidget *widget, GtkCList *clist)
3870 {
3871   gtk_clist_set_reorderable (clist, GTK_TOGGLE_BUTTON (widget)->active);
3872 }
3873
3874 static void
3875 insert_row_clist (GtkWidget *widget, gpointer data)
3876 {
3877   static char *text[] =
3878   {
3879     "This", "is an", "inserted", "row.",
3880     "This", "is an", "inserted", "row.",
3881     "This", "is an", "inserted", "row."
3882   };
3883
3884   static GtkStyle *style1 = NULL;
3885   static GtkStyle *style2 = NULL;
3886   static GtkStyle *style3 = NULL;
3887   gint row;
3888   
3889   if (GTK_CLIST (data)->focus_row >= 0)
3890     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
3891                             text);
3892   else
3893     row = gtk_clist_prepend (GTK_CLIST (data), text);
3894
3895   if (!style1)
3896     {
3897       GdkColor col1;
3898       GdkColor col2;
3899
3900       col1.red   = 0;
3901       col1.green = 56000;
3902       col1.blue  = 0;
3903       col2.red   = 32000;
3904       col2.green = 0;
3905       col2.blue  = 56000;
3906
3907       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
3908       style1->base[GTK_STATE_NORMAL] = col1;
3909       style1->base[GTK_STATE_SELECTED] = col2;
3910
3911       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
3912       style2->fg[GTK_STATE_NORMAL] = col1;
3913       style2->fg[GTK_STATE_SELECTED] = col2;
3914
3915       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
3916       style3->fg[GTK_STATE_NORMAL] = col1;
3917       style3->base[GTK_STATE_NORMAL] = col2;
3918       gdk_font_unref (style3->font);
3919       style3->font =
3920         gdk_font_load ("-*-courier-medium-*-*-*-*-120-*-*-*-*-*-*");
3921     }
3922
3923   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
3924   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
3925   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
3926
3927   clist_rows++;
3928 }
3929
3930 static void
3931 clist_warning_test (GtkWidget *button,
3932                     GtkWidget *clist)
3933 {
3934   GtkWidget *child;
3935   static gboolean add_remove = FALSE;
3936
3937   add_remove = !add_remove;
3938
3939   child = gtk_label_new ("Test");
3940   gtk_widget_ref (child);
3941   gtk_object_sink (GTK_OBJECT (child));
3942
3943   if (add_remove)
3944     gtk_container_add (GTK_CONTAINER (clist), child);
3945   else
3946     {
3947       child->parent = clist;
3948       gtk_container_remove (GTK_CONTAINER (clist), child);
3949       child->parent = NULL;
3950     }
3951
3952   gtk_widget_destroy (child);
3953   gtk_widget_unref (child);
3954 }
3955
3956 static void
3957 undo_selection (GtkWidget *button, GtkCList *clist)
3958 {
3959   gtk_clist_undo_selection (clist);
3960 }
3961
3962 static void 
3963 clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
3964 {
3965   gint i;
3966
3967   if (!GTK_WIDGET_MAPPED (widget))
3968     return;
3969
3970   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3971                     (((GtkOptionMenu *)clist_omenu)->menu_item), i);
3972
3973   gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
3974 }
3975
3976 static void 
3977 clist_click_column (GtkCList *clist, gint column, gpointer data)
3978 {
3979   if (column == 4)
3980     gtk_clist_set_column_visibility (clist, column, FALSE);
3981   else if (column == clist->sort_column)
3982     {
3983       if (clist->sort_type == GTK_SORT_ASCENDING)
3984         clist->sort_type = GTK_SORT_DESCENDING;
3985       else
3986         clist->sort_type = GTK_SORT_ASCENDING;
3987     }
3988   else
3989     gtk_clist_set_sort_column (clist, column);
3990
3991   gtk_clist_sort (clist);
3992 }
3993
3994 static void
3995 create_clist (void)
3996 {
3997   gint i;
3998   static GtkWidget *window = NULL;
3999
4000   static char *titles[] =
4001   {
4002     "auto resize", "not resizeable", "max width 100", "min width 50",
4003     "hide column", "Title 5", "Title 6", "Title 7",
4004     "Title 8",  "Title 9",  "Title 10", "Title 11"
4005   };
4006
4007   static OptionMenuItem items[] =
4008   {
4009     { "Single",   clist_toggle_sel_mode },
4010     { "Browse",   clist_toggle_sel_mode },
4011     { "Multiple", clist_toggle_sel_mode },
4012     { "Extended", clist_toggle_sel_mode }
4013   };
4014
4015   char text[TESTGTK_CLIST_COLUMNS][50];
4016   char *texts[TESTGTK_CLIST_COLUMNS];
4017
4018   GtkWidget *vbox;
4019   GtkWidget *hbox;
4020   GtkWidget *clist;
4021   GtkWidget *button;
4022   GtkWidget *separator;
4023   GtkWidget *scrolled_win;
4024   GtkWidget *check;
4025
4026   GtkWidget *undo_button;
4027   GtkWidget *label;
4028
4029   GtkStyle *style;
4030   GdkColor col1;
4031   GdkColor col2;
4032
4033   if (!window)
4034     {
4035       clist_rows = 0;
4036       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4037
4038       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4039                           GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
4040
4041       gtk_window_set_title (GTK_WINDOW (window), "clist");
4042       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4043
4044       vbox = gtk_vbox_new (FALSE, 0);
4045       gtk_container_add (GTK_CONTAINER (window), vbox);
4046
4047       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
4048       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
4049       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
4050                                       GTK_POLICY_AUTOMATIC, 
4051                                       GTK_POLICY_AUTOMATIC);
4052
4053       /* create GtkCList here so we have a pointer to throw at the 
4054        * button callbacks -- more is done with it later */
4055       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
4056       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
4057       gtk_signal_connect (GTK_OBJECT (clist), "click_column",
4058                           (GtkSignalFunc) clist_click_column, NULL);
4059
4060       /* control buttons */
4061       hbox = gtk_hbox_new (FALSE, 5);
4062       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4063       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4064
4065       button = gtk_button_new_with_label ("Insert Row");
4066       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4067       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4068                           (GtkSignalFunc) insert_row_clist, (gpointer) clist);
4069
4070       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
4071       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4072       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4073                           (GtkSignalFunc) add1000_clist, (gpointer) clist);
4074
4075       button = gtk_button_new_with_label ("Add 10,000 Rows");
4076       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4077       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4078                           (GtkSignalFunc) add10000_clist, (gpointer) clist);
4079
4080       /* second layer of buttons */
4081       hbox = gtk_hbox_new (FALSE, 5);
4082       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4083       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4084
4085       button = gtk_button_new_with_label ("Clear List");
4086       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4087       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4088                           (GtkSignalFunc) clear_clist, (gpointer) clist);
4089
4090       button = gtk_button_new_with_label ("Remove Selection");
4091       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4092       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4093                           (GtkSignalFunc) clist_remove_selection,
4094                           (gpointer) clist);
4095
4096       undo_button = gtk_button_new_with_label ("Undo Selection");
4097       gtk_box_pack_start (GTK_BOX (hbox), undo_button, TRUE, TRUE, 0);
4098       gtk_signal_connect (GTK_OBJECT (undo_button), "clicked",
4099                           (GtkSignalFunc) undo_selection, (gpointer) clist);
4100
4101       button = gtk_button_new_with_label ("Warning Test");
4102       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4103       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4104                           (GtkSignalFunc) clist_warning_test,(gpointer) clist);
4105
4106       /* third layer of buttons */
4107       hbox = gtk_hbox_new (FALSE, 5);
4108       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4109       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4110
4111       check = gtk_check_button_new_with_label ("Show Title Buttons");
4112       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
4113       gtk_signal_connect (GTK_OBJECT (check), "clicked",
4114                           GTK_SIGNAL_FUNC (toggle_title_buttons), clist);
4115       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
4116
4117       check = gtk_check_button_new_with_label ("Reorderable");
4118       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
4119       gtk_signal_connect (GTK_OBJECT (check), "clicked",
4120                           GTK_SIGNAL_FUNC (toggle_reorderable), clist);
4121       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
4122
4123       label = gtk_label_new ("Selection Mode :");
4124       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4125
4126       clist_omenu = build_option_menu (items, 4, 3, clist);
4127       gtk_box_pack_start (GTK_BOX (hbox), clist_omenu, FALSE, TRUE, 0);
4128
4129       /* 
4130        * the rest of the clist configuration
4131        */
4132
4133       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
4134       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
4135       gtk_widget_set_usize (clist, -1, 300);
4136
4137       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
4138         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
4139
4140       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
4141       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
4142       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
4143       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
4144       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
4145       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
4146                                           GTK_JUSTIFY_RIGHT);
4147       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
4148                                           GTK_JUSTIFY_CENTER);
4149       
4150       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
4151         {
4152           texts[i] = text[i];
4153           sprintf (text[i], "Column %d", i);
4154         }
4155
4156       sprintf (text[1], "Right");
4157       sprintf (text[2], "Center");
4158
4159       col1.red   = 56000;
4160       col1.green = 0;
4161       col1.blue  = 0;
4162       col2.red   = 0;
4163       col2.green = 56000;
4164       col2.blue  = 32000;
4165
4166       style = gtk_style_new ();
4167       style->fg[GTK_STATE_NORMAL] = col1;
4168       style->base[GTK_STATE_NORMAL] = col2;
4169       
4170       gdk_font_unref (style->font);
4171       style->font =
4172         gdk_font_load ("-adobe-helvetica-bold-r-*-*-*-140-*-*-*-*-*-*");
4173
4174       for (i = 0; i < 10; i++)
4175         {
4176           sprintf (text[0], "CListRow %d", clist_rows++);
4177           gtk_clist_append (GTK_CLIST (clist), texts);
4178
4179           switch (i % 4)
4180             {
4181             case 2:
4182               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
4183               break;
4184             default:
4185               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
4186               break;
4187             }
4188         }
4189
4190       separator = gtk_hseparator_new ();
4191       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
4192
4193       hbox = gtk_hbox_new (FALSE, 0);
4194       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4195
4196       button = gtk_button_new_with_label ("close");
4197       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
4198       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4199       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4200                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
4201                                  GTK_OBJECT (window));
4202
4203       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4204       gtk_widget_grab_default (button);
4205     }
4206
4207   if (!GTK_WIDGET_VISIBLE (window))
4208     gtk_widget_show_all (window);
4209   else
4210     {
4211       clist_rows = 0;
4212       gtk_widget_destroy (window);
4213     }
4214 }
4215
4216 /*
4217  * GtkCTree
4218  */
4219
4220 GdkPixmap *pixmap1;
4221 GdkPixmap *pixmap2;
4222 GdkPixmap *pixmap3;
4223 GdkBitmap *mask1;
4224 GdkBitmap *mask2;
4225 GdkBitmap *mask3;
4226
4227 static gint books = 0;
4228 static gint pages = 0;
4229
4230 static GtkWidget *book_label;
4231 static GtkWidget *page_label;
4232 static GtkWidget *sel_label;
4233 static GtkWidget *vis_label;
4234 static GtkWidget *omenu1;
4235 static GtkWidget *omenu2;
4236 static GtkWidget *omenu3;
4237 static GtkWidget *omenu4;
4238 static GtkWidget *spin1;
4239 static GtkWidget *spin2;
4240 static GtkWidget *spin3;
4241 static gint line_style;
4242
4243 void after_press (GtkCTree *ctree, gpointer data)
4244 {
4245   char buf[80];
4246
4247   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
4248   gtk_label_set_text (GTK_LABEL (sel_label), buf);
4249
4250   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
4251   gtk_label_set_text (GTK_LABEL (vis_label), buf);
4252
4253   sprintf (buf, "%d", books);
4254   gtk_label_set_text (GTK_LABEL (book_label), buf);
4255
4256   sprintf (buf, "%d", pages);
4257   gtk_label_set_text (GTK_LABEL (page_label), buf);
4258 }
4259
4260 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
4261                  GtkCTreeNode *sibling, gpointer data)
4262 {
4263   char *source;
4264   char *target1;
4265   char *target2;
4266
4267   gtk_ctree_get_node_info (ctree, child, &source, 
4268                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4269   if (parent)
4270     gtk_ctree_get_node_info (ctree, parent, &target1, 
4271                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4272   if (sibling)
4273     gtk_ctree_get_node_info (ctree, sibling, &target2, 
4274                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
4275
4276   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
4277            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
4278 }
4279
4280 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
4281 {
4282   if (GTK_CTREE_ROW (list)->is_leaf)
4283     pages--;
4284   else
4285     books--;
4286 }
4287
4288 void expand_all (GtkWidget *widget, GtkCTree *ctree)
4289 {
4290   gtk_ctree_expand_recursive (ctree, NULL);
4291   after_press (ctree, NULL);
4292 }
4293
4294 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
4295 {
4296   gtk_ctree_collapse_recursive (ctree, NULL);
4297   after_press (ctree, NULL);
4298 }
4299
4300 void select_all (GtkWidget *widget, GtkCTree *ctree)
4301 {
4302   gtk_ctree_select_recursive (ctree, NULL);
4303   after_press (ctree, NULL);
4304 }
4305
4306 void change_style (GtkWidget *widget, GtkCTree *ctree)
4307 {
4308   static GtkStyle *style1 = NULL;
4309   static GtkStyle *style2 = NULL;
4310
4311   GtkCTreeNode *node;
4312   GdkColor col1;
4313   GdkColor col2;
4314
4315   if (GTK_CLIST (ctree)->focus_row >= 0)
4316     node = GTK_CTREE_NODE
4317       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
4318   else
4319     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
4320
4321   if (!node)
4322     return;
4323
4324   if (!style1)
4325     {
4326       col1.red   = 0;
4327       col1.green = 56000;
4328       col1.blue  = 0;
4329       col2.red   = 32000;
4330       col2.green = 0;
4331       col2.blue  = 56000;
4332
4333       style1 = gtk_style_new ();
4334       style1->base[GTK_STATE_NORMAL] = col1;
4335       style1->fg[GTK_STATE_SELECTED] = col2;
4336
4337       style2 = gtk_style_new ();
4338       style2->base[GTK_STATE_SELECTED] = col2;
4339       style2->fg[GTK_STATE_NORMAL] = col1;
4340       style2->base[GTK_STATE_NORMAL] = col2;
4341       gdk_font_unref (style2->font);
4342       style2->font =
4343         gdk_font_load ("-*-courier-medium-*-*-*-*-300-*-*-*-*-*-*");
4344     }
4345
4346   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
4347   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
4348
4349   if (GTK_CTREE_ROW (node)->children)
4350     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
4351                                   style2);
4352 }
4353
4354 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
4355 {
4356   gtk_ctree_unselect_recursive (ctree, NULL);
4357   after_press (ctree, NULL);
4358 }
4359
4360 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
4361 {
4362   GtkCList *clist;
4363   GtkCTreeNode *node;
4364
4365   clist = GTK_CLIST (ctree);
4366
4367   gtk_clist_freeze (clist);
4368
4369   while (clist->selection)
4370     {
4371       node = clist->selection->data;
4372
4373       if (GTK_CTREE_ROW (node)->is_leaf)
4374         pages--;
4375       else
4376         gtk_ctree_post_recursive (ctree, node,
4377                                   (GtkCTreeFunc) count_items, NULL);
4378
4379       gtk_ctree_remove_node (ctree, node);
4380
4381       if (clist->selection_mode == GTK_SELECTION_BROWSE)
4382         break;
4383     }
4384
4385   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
4386       clist->focus_row >= 0)
4387     {
4388       node = gtk_ctree_node_nth (ctree, clist->focus_row);
4389
4390       if (node)
4391         gtk_ctree_select (ctree, node);
4392     }
4393     
4394   gtk_clist_thaw (clist);
4395   after_press (ctree, NULL);
4396 }
4397
4398 struct _ExportStruct {
4399   gchar *tree;
4400   gchar *info;
4401   gboolean is_leaf;
4402 };
4403
4404 typedef struct _ExportStruct ExportStruct;
4405
4406 gboolean
4407 gnode2ctree (GtkCTree   *ctree,
4408              guint       depth,
4409              GNode        *gnode,
4410              GtkCTreeNode *cnode,
4411              gpointer    data)
4412 {
4413   ExportStruct *es;
4414   GdkPixmap *pixmap_closed;
4415   GdkBitmap *mask_closed;
4416   GdkPixmap *pixmap_opened;
4417   GdkBitmap *mask_opened;
4418
4419   if (!cnode || !gnode || (!(es = gnode->data)))
4420     return FALSE;
4421
4422   if (es->is_leaf)
4423     {
4424       pixmap_closed = pixmap3;
4425       mask_closed = mask3;
4426       pixmap_opened = NULL;
4427       mask_opened = NULL;
4428     }
4429   else
4430     {
4431       pixmap_closed = pixmap1;
4432       mask_closed = mask1;
4433       pixmap_opened = pixmap2;
4434       mask_opened = mask2;
4435     }
4436
4437   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
4438                            mask_closed, pixmap_opened, mask_opened,
4439                            es->is_leaf, (depth < 3));
4440   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
4441   g_free (es);
4442   gnode->data = NULL;
4443
4444   return TRUE;
4445 }
4446
4447 gboolean
4448 ctree2gnode (GtkCTree   *ctree,
4449              guint       depth,
4450              GNode        *gnode,
4451              GtkCTreeNode *cnode,
4452              gpointer    data)
4453 {
4454   ExportStruct *es;
4455
4456   if (!cnode || !gnode)
4457     return FALSE;
4458   
4459   es = g_new (ExportStruct, 1);
4460   gnode->data = es;
4461   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
4462   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
4463   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
4464   return TRUE;
4465 }
4466
4467 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
4468 {
4469   char *title[] = { "Tree" , "Info" };
4470   static GtkWidget *export_window = NULL;
4471   static GtkCTree *export_ctree;
4472   GtkWidget *vbox;
4473   GtkWidget *scrolled_win;
4474   GtkWidget *button;
4475   GtkWidget *sep;
4476   GNode *gnode;
4477   GtkCTreeNode *node;
4478
4479   if (!export_window)
4480     {
4481       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4482   
4483       gtk_signal_connect (GTK_OBJECT (export_window), "destroy",
4484                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4485                           &export_window);
4486
4487       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
4488       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
4489
4490       vbox = gtk_vbox_new (FALSE, 0);
4491       gtk_container_add (GTK_CONTAINER (export_window), vbox);
4492       
4493       button = gtk_button_new_with_label ("Close");
4494       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
4495
4496       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4497                                  (GtkSignalFunc) gtk_widget_destroy,
4498                                  GTK_OBJECT(export_window));
4499
4500       sep = gtk_hseparator_new ();
4501       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
4502
4503       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
4504       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
4505
4506       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
4507       gtk_container_add (GTK_CONTAINER (scrolled_win),
4508                          GTK_WIDGET (export_ctree));
4509       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
4510                                       GTK_POLICY_AUTOMATIC,
4511                                       GTK_POLICY_AUTOMATIC);
4512       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
4513       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
4514                                     GTK_SELECTION_EXTENDED);
4515       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
4516       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
4517       gtk_widget_set_usize (GTK_WIDGET (export_ctree), 300, 200);
4518     }
4519
4520   if (!GTK_WIDGET_VISIBLE (export_window))
4521     gtk_widget_show_all (export_window);
4522       
4523   gtk_clist_clear (GTK_CLIST (export_ctree));
4524
4525   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
4526                                      GTK_CLIST (ctree)->focus_row));
4527   if (!node)
4528     return;
4529
4530   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
4531                                      ctree2gnode, NULL);
4532   if (gnode)
4533     {
4534       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
4535                               gnode2ctree, NULL);
4536       g_node_destroy (gnode);
4537     }
4538 }
4539
4540 void change_indent (GtkWidget *widget, GtkCTree *ctree)
4541 {
4542   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
4543 }
4544
4545 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
4546 {
4547   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
4548 }
4549
4550 void change_row_height (GtkWidget *widget, GtkCList *clist)
4551 {
4552   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
4553 }
4554
4555 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
4556 {
4557   GtkStyle *style = NULL;
4558   
4559   if (!node)
4560     return;
4561   
4562   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
4563     {
4564       if (!GTK_CTREE_ROW (node)->is_leaf)
4565         style = GTK_CTREE_ROW (node)->row.data;
4566       else if (GTK_CTREE_ROW (node)->parent)
4567         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
4568     }
4569
4570   gtk_ctree_node_set_row_style (ctree, node, style);
4571 }
4572
4573 void ctree_toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
4574 {
4575   gint i;
4576
4577   if (!GTK_WIDGET_MAPPED (widget))
4578     return;
4579
4580   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4581                     (((GtkOptionMenu *)omenu1)->menu_item), i);
4582   
4583   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
4584        ((GtkCTreeLineStyle) (3 - i)) != GTK_CTREE_LINES_TABBED) ||
4585       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
4586        ((GtkCTreeLineStyle) (3 - i)) == GTK_CTREE_LINES_TABBED))
4587     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
4588   gtk_ctree_set_line_style (ctree, 3 - i);
4589   line_style = 3 - i;
4590 }
4591
4592 void ctree_toggle_expander_style (GtkWidget *widget, GtkCTree *ctree)
4593 {
4594   gint i;
4595
4596   if (!GTK_WIDGET_MAPPED (widget))
4597     return;
4598
4599   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4600                     (((GtkOptionMenu *)omenu2)->menu_item), i);
4601   
4602   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) (3 - i));
4603 }
4604
4605 void ctree_toggle_justify (GtkWidget *widget, GtkCTree *ctree)
4606 {
4607   gint i;
4608
4609   if (!GTK_WIDGET_MAPPED (widget))
4610     return;
4611
4612   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4613                     (((GtkOptionMenu *)omenu3)->menu_item), i);
4614
4615   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
4616                                       (GtkJustification) (1 - i));
4617 }
4618
4619 void ctree_toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
4620 {
4621   gint i;
4622
4623   if (!GTK_WIDGET_MAPPED (widget))
4624     return;
4625
4626   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
4627                     (((GtkOptionMenu *)omenu4)->menu_item), i);
4628
4629   gtk_clist_set_selection_mode (GTK_CLIST (ctree), (GtkSelectionMode) (3 - i));
4630   after_press (ctree, NULL);
4631 }
4632     
4633 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
4634                       gint num_books, gint num_pages, GtkCTreeNode *parent)
4635 {
4636   gchar *text[2];
4637   gchar buf1[60];
4638   gchar buf2[60];
4639   GtkCTreeNode *sibling;
4640   gint i;
4641
4642   text[0] = buf1;
4643   text[1] = buf2;
4644   sibling = NULL;
4645
4646   for (i = num_pages + num_books; i > num_books; i--)
4647     {
4648       pages++;
4649       sprintf (buf1, "Page %02d", (gint) rand() % 100);
4650       sprintf (buf2, "Item %d-%d", cur_depth, i);
4651       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
4652                                        pixmap3, mask3, NULL, NULL,
4653                                        TRUE, FALSE);
4654
4655       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
4656         gtk_ctree_node_set_row_style (ctree, sibling,
4657                                       GTK_CTREE_ROW (parent)->row.style);
4658     }
4659
4660   if (cur_depth == depth)
4661     return;
4662
4663   for (i = num_books; i > 0; i--)
4664     {
4665       GtkStyle *style;
4666
4667       books++;
4668       sprintf (buf1, "Book %02d", (gint) rand() % 100);
4669       sprintf (buf2, "Item %d-%d", cur_depth, i);
4670       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
4671                                        pixmap1, mask1, pixmap2, mask2,
4672                                        FALSE, FALSE);
4673
4674       style = gtk_style_new ();
4675       switch (cur_depth % 3)
4676         {
4677         case 0:
4678           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
4679           style->base[GTK_STATE_NORMAL].green = 0;
4680           style->base[GTK_STATE_NORMAL].blue  = 65535 - ((i * 10000) % 65535);
4681           break;
4682         case 1:
4683           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
4684           style->base[GTK_STATE_NORMAL].green = 65535 - ((i * 10000) % 65535);
4685           style->base[GTK_STATE_NORMAL].blue  = 0;
4686           break;
4687         default:
4688           style->base[GTK_STATE_NORMAL].red   = 65535 - ((i * 10000) % 65535);
4689           style->base[GTK_STATE_NORMAL].green = 0;
4690           style->base[GTK_STATE_NORMAL].blue  = 10000 * (cur_depth % 6);
4691           break;
4692         }
4693       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
4694                                         (GtkDestroyNotify) gtk_style_unref);
4695
4696       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
4697         gtk_ctree_node_set_row_style (ctree, sibling, style);
4698
4699       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
4700                        sibling);
4701     }
4702 }
4703
4704 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
4705 {
4706   gchar *text [2];
4707   gchar label1[] = "Root";
4708   gchar label2[] = "";
4709   GtkCTreeNode *parent;
4710   GtkStyle *style;
4711   guint b, d, p, n;
4712
4713   text[0] = label1;
4714   text[1] = label2;
4715   
4716   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
4717   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
4718   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
4719
4720   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
4721
4722   if (n > 100000)
4723     {
4724       g_print ("%d total items? Try less\n",n);
4725       return;
4726     }
4727
4728   gtk_clist_freeze (GTK_CLIST (ctree));
4729   gtk_clist_clear (GTK_CLIST (ctree));
4730
4731   books = 1;
4732   pages = 0;
4733
4734   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmap1,
4735                                   mask1, pixmap2, mask2, FALSE, TRUE);
4736
4737   style = gtk_style_new ();
4738   style->base[GTK_STATE_NORMAL].red   = 0;
4739   style->base[GTK_STATE_NORMAL].green = 45000;
4740   style->base[GTK_STATE_NORMAL].blue  = 55000;
4741   gtk_ctree_node_set_row_data_full (ctree, parent, style,
4742                                     (GtkDestroyNotify) gtk_style_unref);
4743
4744   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
4745     gtk_ctree_node_set_row_style (ctree, parent, style);
4746
4747   build_recursive (ctree, 1, d, b, p, parent);
4748   gtk_clist_thaw (GTK_CLIST (ctree));
4749   after_press (ctree, NULL);
4750 }
4751
4752 static void 
4753 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
4754 {
4755   GtkCList *clist;
4756
4757   clist = GTK_CLIST (ctree);
4758
4759   if (column == clist->sort_column)
4760     {
4761       if (clist->sort_type == GTK_SORT_ASCENDING)
4762         clist->sort_type = GTK_SORT_DESCENDING;
4763       else
4764         clist->sort_type = GTK_SORT_ASCENDING;
4765     }
4766   else
4767     gtk_clist_set_sort_column (clist, column);
4768
4769   gtk_ctree_sort_recursive (ctree, NULL);
4770 }
4771
4772 void create_ctree (void)
4773 {
4774   static GtkWidget *window = NULL;
4775   GtkTooltips *tooltips;
4776   GtkCTree *ctree;
4777   GtkWidget *scrolled_win;
4778   GtkWidget *vbox;
4779   GtkWidget *bbox;
4780   GtkWidget *mbox;
4781   GtkWidget *hbox;
4782   GtkWidget *hbox2;
4783   GtkWidget *frame;
4784   GtkWidget *label;
4785   GtkWidget *button;
4786   GtkWidget *check;
4787   GtkAdjustment *adj;
4788   GtkWidget *spinner;
4789   GdkColor transparent = { 0 };
4790
4791   char *title[] = { "Tree" , "Info" };
4792   char buf[80];
4793
4794   static OptionMenuItem items1[] =
4795   {
4796     { "No lines", ctree_toggle_line_style },
4797     { "Solid",    ctree_toggle_line_style },
4798     { "Dotted",   ctree_toggle_line_style },
4799     { "Tabbed",   ctree_toggle_line_style }
4800   };
4801
4802   static OptionMenuItem items2[] =
4803   {
4804     { "None",     ctree_toggle_expander_style },
4805     { "Square",   ctree_toggle_expander_style },
4806     { "Triangle", ctree_toggle_expander_style },
4807     { "Circular", ctree_toggle_expander_style }
4808   };
4809
4810   static OptionMenuItem items3[] =
4811   {
4812     { "Left",  ctree_toggle_justify },
4813     { "Right", ctree_toggle_justify }
4814   };
4815
4816   static OptionMenuItem items4[] =
4817   {
4818     { "Single",   ctree_toggle_sel_mode },
4819     { "Browse",   ctree_toggle_sel_mode },
4820     { "Multiple", ctree_toggle_sel_mode },
4821     { "Extended", ctree_toggle_sel_mode }
4822   };
4823
4824   if (!window)
4825     {
4826       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4827
4828       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4829                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4830                           &window);
4831
4832       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
4833       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4834
4835       tooltips = gtk_tooltips_new ();
4836       gtk_object_ref (GTK_OBJECT (tooltips));
4837       gtk_object_sink (GTK_OBJECT (tooltips));
4838
4839       gtk_object_set_data_full (GTK_OBJECT (window), "tooltips", tooltips,
4840                                 (GtkDestroyNotify) gtk_object_unref);
4841
4842       vbox = gtk_vbox_new (FALSE, 0);
4843       gtk_container_add (GTK_CONTAINER (window), vbox);
4844
4845       hbox = gtk_hbox_new (FALSE, 5);
4846       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4847       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4848       
4849       label = gtk_label_new ("Depth :");
4850       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4851       
4852       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
4853       spin1 = gtk_spin_button_new (adj, 0, 0);
4854       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
4855   
4856       label = gtk_label_new ("Books :");
4857       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4858       
4859       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
4860       spin2 = gtk_spin_button_new (adj, 0, 0);
4861       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
4862
4863       label = gtk_label_new ("Pages :");
4864       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4865       
4866       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
4867       spin3 = gtk_spin_button_new (adj, 0, 0);
4868       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
4869
4870       button = gtk_button_new_with_label ("Close");
4871       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4872
4873       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4874                                  (GtkSignalFunc) gtk_widget_destroy,
4875                                  GTK_OBJECT(window));
4876
4877       button = gtk_button_new_with_label ("Rebuild Tree");
4878       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4879
4880       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
4881       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
4882       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
4883                                       GTK_POLICY_AUTOMATIC,
4884                                       GTK_POLICY_ALWAYS);
4885       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
4886
4887       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
4888       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
4889
4890       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
4891       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
4892       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
4893       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
4894       line_style = GTK_CTREE_LINES_DOTTED;
4895
4896       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4897                           GTK_SIGNAL_FUNC (rebuild_tree), ctree);
4898       gtk_signal_connect (GTK_OBJECT (ctree), "click_column",
4899                           (GtkSignalFunc) ctree_click_column, NULL);
4900
4901       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
4902                                 GTK_SIGNAL_FUNC (after_press), NULL);
4903       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
4904                                 GTK_SIGNAL_FUNC (after_press), NULL);
4905       gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
4906                                 GTK_SIGNAL_FUNC (after_move), NULL);
4907       gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
4908                                 GTK_SIGNAL_FUNC (after_press), NULL);
4909       gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
4910                                 GTK_SIGNAL_FUNC (after_press), NULL);
4911       gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
4912                                 GTK_SIGNAL_FUNC (after_press), NULL);
4913       gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
4914                                 GTK_SIGNAL_FUNC (after_press), NULL);
4915       gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
4916                                 GTK_SIGNAL_FUNC (after_press), NULL);
4917
4918       bbox = gtk_hbox_new (FALSE, 5);
4919       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
4920       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
4921
4922       mbox = gtk_vbox_new (TRUE, 5);
4923       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4924
4925       label = gtk_label_new ("Row Height :");
4926       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4927
4928       label = gtk_label_new ("Indent :");
4929       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4930
4931       label = gtk_label_new ("Spacing :");
4932       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
4933
4934       mbox = gtk_vbox_new (TRUE, 5);
4935       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4936
4937       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
4938       spinner = gtk_spin_button_new (adj, 0, 0);
4939       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4940       gtk_tooltips_set_tip (tooltips, spinner,
4941                             "Row height of list items", NULL);
4942       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4943                           GTK_SIGNAL_FUNC (change_row_height), ctree);
4944       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
4945
4946       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
4947       spinner = gtk_spin_button_new (adj, 0, 0);
4948       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4949       gtk_tooltips_set_tip (tooltips, spinner, "Tree Indentation.", NULL);
4950       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4951                           GTK_SIGNAL_FUNC (change_indent), ctree);
4952
4953       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
4954       spinner = gtk_spin_button_new (adj, 0, 0);
4955       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
4956       gtk_tooltips_set_tip (tooltips, spinner, "Tree Spacing.", NULL);
4957       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4958                           GTK_SIGNAL_FUNC (change_spacing), ctree);
4959
4960       mbox = gtk_vbox_new (TRUE, 5);
4961       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
4962
4963       hbox = gtk_hbox_new (FALSE, 5);
4964       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
4965
4966       button = gtk_button_new_with_label ("Expand All");
4967       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4968       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4969                           GTK_SIGNAL_FUNC (expand_all), ctree);
4970
4971       button = gtk_button_new_with_label ("Collapse All");
4972       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4973       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4974                           GTK_SIGNAL_FUNC (collapse_all), ctree);
4975
4976       button = gtk_button_new_with_label ("Change Style");
4977       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4978       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4979                           GTK_SIGNAL_FUNC (change_style), ctree);
4980
4981       button = gtk_button_new_with_label ("Export Tree");
4982       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4983       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4984                           GTK_SIGNAL_FUNC (export_ctree), ctree);
4985
4986       hbox = gtk_hbox_new (FALSE, 5);
4987       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
4988
4989       button = gtk_button_new_with_label ("Select All");
4990       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4991       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4992                           GTK_SIGNAL_FUNC (select_all), ctree);
4993
4994       button = gtk_button_new_with_label ("Unselect All");
4995       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4996       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4997                           GTK_SIGNAL_FUNC (unselect_all), ctree);
4998
4999       button = gtk_button_new_with_label ("Remove Selection");
5000       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5001       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5002                           GTK_SIGNAL_FUNC (remove_selection), ctree);
5003
5004       check = gtk_check_button_new_with_label ("Reorderable");
5005       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5006       gtk_tooltips_set_tip (tooltips, check,
5007                             "Tree items can be reordered by dragging.", NULL);
5008       gtk_signal_connect (GTK_OBJECT (check), "clicked",
5009                           GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
5010       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5011
5012       hbox = gtk_hbox_new (TRUE, 5);
5013       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
5014
5015       omenu1 = build_option_menu (items1, 4, 2, ctree);
5016       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
5017       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
5018
5019       omenu2 = build_option_menu (items2, 4, 1, ctree);
5020       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
5021       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
5022                             NULL);
5023
5024       omenu3 = build_option_menu (items3, 2, 0, ctree);
5025       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
5026       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
5027                             NULL);
5028
5029       omenu4 = build_option_menu (items4, 4, 3, ctree);
5030       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
5031       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
5032                             NULL);
5033
5034       gtk_widget_realize (window);
5035
5036       pixmap1 = gdk_pixmap_create_from_xpm_d (window->window, &mask1, 
5037                                               &transparent, book_closed_xpm);
5038       pixmap2 = gdk_pixmap_create_from_xpm_d (window->window, &mask2, 
5039                                               &transparent, book_open_xpm);
5040       pixmap3 = gdk_pixmap_create_from_xpm_d (window->window, &mask3,
5041                                               &transparent, mini_page_xpm);
5042
5043       gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
5044
5045       frame = gtk_frame_new (NULL);
5046       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
5047       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
5048       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
5049
5050       hbox = gtk_hbox_new (TRUE, 2);
5051       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
5052       gtk_container_add (GTK_CONTAINER (frame), hbox);
5053
5054       frame = gtk_frame_new (NULL);
5055       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5056       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5057
5058       hbox2 = gtk_hbox_new (FALSE, 0);
5059       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5060       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5061
5062       label = gtk_label_new ("Books :");
5063       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5064
5065       sprintf (buf, "%d", books);
5066       book_label = gtk_label_new (buf);
5067       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
5068
5069       frame = gtk_frame_new (NULL);
5070       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5071       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5072
5073       hbox2 = gtk_hbox_new (FALSE, 0);
5074       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5075       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5076
5077       label = gtk_label_new ("Pages :");
5078       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5079
5080       sprintf (buf, "%d", pages);
5081       page_label = gtk_label_new (buf);
5082       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
5083
5084       frame = gtk_frame_new (NULL);
5085       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5086       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5087
5088       hbox2 = gtk_hbox_new (FALSE, 0);
5089       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5090       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5091
5092       label = gtk_label_new ("Selected :");
5093       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5094
5095       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
5096       sel_label = gtk_label_new (buf);
5097       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
5098
5099       frame = gtk_frame_new (NULL);
5100       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
5101       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
5102
5103       hbox2 = gtk_hbox_new (FALSE, 0);
5104       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
5105       gtk_container_add (GTK_CONTAINER (frame), hbox2);
5106
5107       label = gtk_label_new ("Visible :");
5108       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
5109
5110       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
5111       vis_label = gtk_label_new (buf);
5112       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
5113
5114       rebuild_tree (NULL, ctree);
5115     }
5116
5117   if (!GTK_WIDGET_VISIBLE (window))
5118     gtk_widget_show_all (window);
5119   else
5120     gtk_widget_destroy (window);
5121 }
5122
5123 /*
5124  * GtkColorSelection
5125  */
5126
5127 void
5128 color_selection_ok (GtkWidget               *w,
5129                     GtkColorSelectionDialog *cs)
5130 {
5131   GtkColorSelection *colorsel;
5132   gdouble color[4];
5133
5134   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
5135
5136   gtk_color_selection_get_color(colorsel,color);
5137   gtk_color_selection_set_color(colorsel,color);
5138 }
5139
5140 void
5141 color_selection_changed (GtkWidget *w,
5142                          GtkColorSelectionDialog *cs)
5143 {
5144   GtkColorSelection *colorsel;
5145   gdouble color[4];
5146
5147   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
5148   gtk_color_selection_get_color(colorsel,color);
5149 }
5150
5151 void
5152 create_color_selection (void)
5153 {
5154   static GtkWidget *window = NULL;
5155
5156   if (!window)
5157     {
5158       window = gtk_color_selection_dialog_new ("color selection dialog");
5159
5160       gtk_color_selection_set_opacity (
5161         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5162         TRUE);
5163
5164       gtk_color_selection_set_update_policy(
5165         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5166         GTK_UPDATE_CONTINUOUS);
5167
5168       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5169
5170       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5171                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5172                           &window);
5173
5174       gtk_signal_connect (
5175         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
5176         "color_changed",
5177         GTK_SIGNAL_FUNC(color_selection_changed),
5178         window);
5179
5180       gtk_signal_connect (
5181         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
5182         "clicked",
5183         GTK_SIGNAL_FUNC(color_selection_ok),
5184         window);
5185
5186       gtk_signal_connect_object (
5187         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
5188         "clicked",
5189         GTK_SIGNAL_FUNC(gtk_widget_destroy),
5190         GTK_OBJECT (window));
5191     }
5192
5193   if (!GTK_WIDGET_VISIBLE (window))
5194     gtk_widget_show (window);
5195   else
5196     gtk_widget_destroy (window);
5197 }
5198
5199 /*
5200  * GtkFileSelection
5201  */
5202
5203 void
5204 file_selection_hide_fileops (GtkWidget *widget,
5205                              GtkFileSelection *fs)
5206 {
5207   gtk_file_selection_hide_fileop_buttons (fs);
5208 }
5209
5210 void
5211 file_selection_ok (GtkWidget        *w,
5212                    GtkFileSelection *fs)
5213 {
5214   g_print ("%s\n", gtk_file_selection_get_filename (fs));
5215   gtk_widget_destroy (GTK_WIDGET (fs));
5216 }
5217
5218 void
5219 create_file_selection (void)
5220 {
5221   static GtkWidget *window = NULL;
5222   GtkWidget *button;
5223
5224   if (!window)
5225     {
5226       window = gtk_file_selection_new ("file selection dialog");
5227
5228       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
5229
5230       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5231
5232       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5233                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5234                           &window);
5235
5236       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (window)->ok_button),
5237                           "clicked", GTK_SIGNAL_FUNC(file_selection_ok),
5238                           window);
5239       gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (window)->cancel_button),
5240                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
5241                                  GTK_OBJECT (window));
5242       
5243       button = gtk_button_new_with_label ("Hide Fileops");
5244       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5245                           (GtkSignalFunc) file_selection_hide_fileops, 
5246                           (gpointer) window);
5247       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
5248                           button, FALSE, FALSE, 0);
5249       gtk_widget_show (button);
5250
5251       button = gtk_button_new_with_label ("Show Fileops");
5252       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5253                                  (GtkSignalFunc) gtk_file_selection_show_fileop_buttons, 
5254                                  (gpointer) window);
5255       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
5256                           button, FALSE, FALSE, 0);
5257       gtk_widget_show (button);
5258     }
5259   
5260   if (!GTK_WIDGET_VISIBLE (window))
5261     gtk_widget_show (window);
5262   else
5263     gtk_widget_destroy (window);
5264 }
5265
5266 /*
5267  * GtkFontSelection
5268  */
5269
5270 void
5271 font_selection_ok (GtkWidget              *w,
5272                    GtkFontSelectionDialog *fs)
5273 {
5274   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
5275
5276   g_print ("%s\n", s);
5277   g_free (s);
5278   gtk_widget_destroy (GTK_WIDGET (fs));
5279 }
5280
5281 void
5282 create_font_selection (void)
5283 {
5284   static GtkWidget *window = NULL;
5285
5286   if (!window)
5287     {
5288       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
5289
5290       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
5291
5292       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5293                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5294                           &window);
5295
5296       gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
5297                           "clicked", GTK_SIGNAL_FUNC(font_selection_ok),
5298                           GTK_FONT_SELECTION_DIALOG (window));
5299       gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
5300                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
5301                                  GTK_OBJECT (window));
5302     }
5303   
5304   if (!GTK_WIDGET_VISIBLE (window))
5305     gtk_widget_show (window);
5306   else
5307     gtk_widget_destroy (window);
5308 }
5309
5310 /*
5311  * GtkDialog
5312  */
5313
5314 static GtkWidget *dialog_window = NULL;
5315
5316 static void
5317 label_toggle (GtkWidget  *widget,
5318               GtkWidget **label)
5319 {
5320   if (!(*label))
5321     {
5322       *label = gtk_label_new ("Dialog Test");
5323       gtk_signal_connect (GTK_OBJECT (*label),
5324                           "destroy",
5325                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
5326                           label);
5327       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
5328       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
5329                           *label, TRUE, TRUE, 0);
5330       gtk_widget_show (*label);
5331     }
5332   else
5333     gtk_widget_destroy (*label);
5334 }
5335
5336 static void
5337 create_dialog (void)
5338 {
5339   static GtkWidget *label;
5340   GtkWidget *button;
5341
5342   if (!dialog_window)
5343     {
5344       dialog_window = gtk_dialog_new ();
5345
5346       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
5347                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5348                           &dialog_window);
5349
5350       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5351       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5352       gtk_widget_set_usize (dialog_window, 200, 110);
5353
5354       button = gtk_button_new_with_label ("OK");
5355       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5356       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
5357                           button, TRUE, TRUE, 0);
5358       gtk_widget_grab_default (button);
5359       gtk_widget_show (button);
5360
5361       button = gtk_button_new_with_label ("Toggle");
5362       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5363                           GTK_SIGNAL_FUNC (label_toggle),
5364                           &label);
5365       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5366       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
5367                           button, TRUE, TRUE, 0);
5368       gtk_widget_show (button);
5369
5370       label = NULL;
5371     }
5372
5373   if (!GTK_WIDGET_VISIBLE (dialog_window))
5374     gtk_widget_show (dialog_window);
5375   else
5376     gtk_widget_destroy (dialog_window);
5377 }
5378
5379 /* Event Watcher
5380  */
5381 static gboolean event_watcher_enter_id = 0;
5382 static gboolean event_watcher_leave_id = 0;
5383
5384 static gboolean
5385 event_watcher (GtkObject      *object,
5386                guint           signal_id,
5387                guint           n_params,
5388                GtkArg         *params,
5389                gpointer        data)
5390 {
5391   g_print ("Watch: \"%s\" emitted for %s\n",
5392            gtk_signal_name (signal_id),
5393            gtk_type_name (GTK_OBJECT_TYPE (object)));
5394
5395   return TRUE;
5396 }
5397
5398 static void
5399 event_watcher_down (void)
5400 {
5401   if (event_watcher_enter_id)
5402     {
5403       guint signal_id;
5404
5405       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5406       gtk_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5407       event_watcher_enter_id = 0;
5408       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5409       gtk_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5410       event_watcher_leave_id = 0;
5411     }
5412 }
5413
5414 static void
5415 event_watcher_toggle (void)
5416 {
5417   if (event_watcher_enter_id)
5418     event_watcher_down ();
5419   else
5420     {
5421       guint signal_id;
5422
5423       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5424       event_watcher_enter_id = gtk_signal_add_emission_hook (signal_id, event_watcher, NULL);
5425       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5426       event_watcher_leave_id = gtk_signal_add_emission_hook (signal_id, event_watcher, NULL);
5427     }
5428 }
5429
5430 static void
5431 create_event_watcher (void)
5432 {
5433   GtkWidget *button;
5434
5435   if (!dialog_window)
5436     {
5437       dialog_window = gtk_dialog_new ();
5438
5439       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
5440                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
5441                           &dialog_window);
5442       gtk_signal_connect (GTK_OBJECT (dialog_window),
5443                           "destroy",
5444                           GTK_SIGNAL_FUNC (event_watcher_down),
5445                           NULL);
5446
5447       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5448       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5449       gtk_widget_set_usize (dialog_window, 200, 110);
5450
5451       button = gtk_toggle_button_new_with_label ("Activate Watch");
5452       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5453                           GTK_SIGNAL_FUNC (event_watcher_toggle),
5454                           NULL);
5455       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5456       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
5457                           button, TRUE, TRUE, 0);
5458       gtk_widget_show (button);
5459
5460       button = gtk_button_new_with_label ("Close");
5461       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5462                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
5463                                  (GtkObject*) dialog_window);
5464       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5465       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
5466                           button, TRUE, TRUE, 0);
5467       gtk_widget_grab_default (button);
5468       gtk_widget_show (button);
5469     }
5470
5471   if (!GTK_WIDGET_VISIBLE (dialog_window))
5472     gtk_widget_show (dialog_window);
5473   else
5474     gtk_widget_destroy (dialog_window);
5475 }
5476
5477 /*
5478  * GtkRange
5479  */
5480
5481 static void
5482 create_range_controls (void)
5483 {
5484   static GtkWidget *window = NULL;
5485   GtkWidget *box1;
5486   GtkWidget *box2;
5487   GtkWidget *button;
5488   GtkWidget *scrollbar;
5489   GtkWidget *scale;
5490   GtkWidget *separator;
5491   GtkObject *adjustment;
5492
5493   if (!window)
5494     {
5495       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5496
5497       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5498                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5499                           &window);
5500
5501       gtk_window_set_title (GTK_WINDOW (window), "range controls");
5502       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5503
5504
5505       box1 = gtk_vbox_new (FALSE, 0);
5506       gtk_container_add (GTK_CONTAINER (window), box1);
5507       gtk_widget_show (box1);
5508
5509
5510       box2 = gtk_vbox_new (FALSE, 10);
5511       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5512       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5513       gtk_widget_show (box2);
5514
5515
5516       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5517
5518       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
5519       gtk_widget_set_usize (GTK_WIDGET (scale), 150, 30);
5520       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
5521       gtk_scale_set_digits (GTK_SCALE (scale), 1);
5522       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5523       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5524       gtk_widget_show (scale);
5525
5526       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
5527       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
5528                                    GTK_UPDATE_CONTINUOUS);
5529       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5530       gtk_widget_show (scrollbar);
5531
5532
5533       separator = gtk_hseparator_new ();
5534       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5535       gtk_widget_show (separator);
5536
5537
5538       box2 = gtk_vbox_new (FALSE, 10);
5539       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5540       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5541       gtk_widget_show (box2);
5542
5543
5544       button = gtk_button_new_with_label ("close");
5545       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5546                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5547                                  GTK_OBJECT (window));
5548       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5549       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5550       gtk_widget_grab_default (button);
5551       gtk_widget_show (button);
5552     }
5553
5554   if (!GTK_WIDGET_VISIBLE (window))
5555     gtk_widget_show (window);
5556   else
5557     gtk_widget_destroy (window);
5558 }
5559
5560 /*
5561  * GtkRulers
5562  */
5563
5564 void
5565 create_rulers (void)
5566 {
5567   static GtkWidget *window = NULL;
5568   GtkWidget *table;
5569   GtkWidget *ruler;
5570
5571   if (!window)
5572     {
5573       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5574       gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
5575
5576       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5577                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5578                           &window);
5579
5580       gtk_window_set_title (GTK_WINDOW (window), "rulers");
5581       gtk_widget_set_usize (window, 300, 300);
5582       gtk_widget_set_events (window, 
5583                              GDK_POINTER_MOTION_MASK 
5584                              | GDK_POINTER_MOTION_HINT_MASK);
5585       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5586
5587       table = gtk_table_new (2, 2, FALSE);
5588       gtk_container_add (GTK_CONTAINER (window), table);
5589       gtk_widget_show (table);
5590
5591       ruler = gtk_hruler_new ();
5592       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
5593       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
5594
5595       gtk_signal_connect_object (
5596         GTK_OBJECT (window), 
5597         "motion_notify_event",
5598         GTK_SIGNAL_FUNC(
5599           GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
5600         GTK_OBJECT (ruler));
5601
5602       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
5603                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
5604       gtk_widget_show (ruler);
5605
5606
5607       ruler = gtk_vruler_new ();
5608       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
5609
5610       gtk_signal_connect_object (
5611         GTK_OBJECT (window), 
5612         "motion_notify_event",
5613         GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
5614         GTK_OBJECT (ruler));
5615
5616       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
5617                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
5618       gtk_widget_show (ruler);
5619     }
5620
5621   if (!GTK_WIDGET_VISIBLE (window))
5622     gtk_widget_show (window);
5623   else
5624     gtk_widget_destroy (window);
5625 }
5626
5627 static void
5628 text_toggle_editable (GtkWidget *checkbutton,
5629                        GtkWidget *text)
5630 {
5631    gtk_text_set_editable(GTK_TEXT(text),
5632                           GTK_TOGGLE_BUTTON(checkbutton)->active);
5633 }
5634
5635 static void
5636 text_toggle_word_wrap (GtkWidget *checkbutton,
5637                        GtkWidget *text)
5638 {
5639    gtk_text_set_word_wrap(GTK_TEXT(text),
5640                           GTK_TOGGLE_BUTTON(checkbutton)->active);
5641 }
5642
5643 struct {
5644   GdkColor color;
5645   gchar *name;
5646 } text_colors[] = {
5647  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5648  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5649  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5650  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5651  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
5652  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5653  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5654  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5655 };
5656
5657 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5658
5659 /*
5660  * GtkText
5661  */
5662 void
5663 text_insert_random (GtkWidget *w, GtkText *text)
5664 {
5665   int i;
5666   char c;
5667    for (i=0; i<10; i++)
5668     {
5669       c = 'A' + rand() % ('Z' - 'A');
5670       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
5671       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
5672     }
5673 }
5674
5675 void
5676 create_text (void)
5677 {
5678   int i, j;
5679
5680   static GtkWidget *window = NULL;
5681   GtkWidget *box1;
5682   GtkWidget *box2;
5683   GtkWidget *hbox;
5684   GtkWidget *button;
5685   GtkWidget *check;
5686   GtkWidget *separator;
5687   GtkWidget *scrolled_window;
5688   GtkWidget *text;
5689   GdkFont *font;
5690
5691   FILE *infile;
5692
5693   if (!window)
5694     {
5695       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5696       gtk_widget_set_name (window, "text window");
5697       gtk_widget_set_usize (window, 500, 500);
5698       gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
5699
5700       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5701                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5702                           &window);
5703
5704       gtk_window_set_title (GTK_WINDOW (window), "test");
5705       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5706
5707
5708       box1 = gtk_vbox_new (FALSE, 0);
5709       gtk_container_add (GTK_CONTAINER (window), box1);
5710       gtk_widget_show (box1);
5711
5712
5713       box2 = gtk_vbox_new (FALSE, 10);
5714       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5715       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5716       gtk_widget_show (box2);
5717
5718
5719       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
5720       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
5721       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
5722                                       GTK_POLICY_NEVER,
5723                                       GTK_POLICY_ALWAYS);
5724       gtk_widget_show (scrolled_window);
5725
5726       text = gtk_text_new (NULL, NULL);
5727       gtk_text_set_editable (GTK_TEXT (text), TRUE);
5728       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
5729       gtk_widget_grab_focus (text);
5730       gtk_widget_show (text);
5731
5732
5733       gtk_text_freeze (GTK_TEXT (text));
5734
5735       font = gdk_font_load ("-adobe-courier-medium-r-normal--*-120-*-*-*-*-*-*");
5736
5737       for (i=0; i<ntext_colors; i++)
5738         {
5739           gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, 
5740                            text_colors[i].name, -1);
5741           gtk_text_insert (GTK_TEXT (text), font, NULL, NULL, "\t", -1);
5742
5743           for (j=0; j<ntext_colors; j++)
5744             {
5745               gtk_text_insert (GTK_TEXT (text), font,
5746                                &text_colors[j].color, &text_colors[i].color,
5747                                "XYZ", -1);
5748             }
5749           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
5750         }
5751
5752       /* The Text widget will reference count the font, so we
5753        * unreference it here
5754        */
5755       gdk_font_unref (font);
5756
5757       infile = fopen("testgtk.c", "r");
5758       
5759       if (infile)
5760         {
5761           char *buffer;
5762           int nbytes_read, nbytes_alloc;
5763           
5764           nbytes_read = 0;
5765           nbytes_alloc = 1024;
5766           buffer = g_new (char, nbytes_alloc);
5767           while (1)
5768             {
5769               int len;
5770               if (nbytes_alloc < nbytes_read + 1024)
5771                 {
5772                   nbytes_alloc *= 2;
5773                   buffer = g_realloc (buffer, nbytes_alloc);
5774                 }
5775               len = fread (buffer + nbytes_read, 1, 1024, infile);
5776               nbytes_read += len;
5777               if (len < 1024)
5778                 break;
5779             }
5780           
5781           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
5782                            NULL, buffer, nbytes_read);
5783           g_free(buffer);
5784           fclose (infile);
5785         }
5786       
5787       gtk_text_thaw (GTK_TEXT (text));
5788
5789       hbox = gtk_hbutton_box_new ();
5790       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
5791       gtk_widget_show (hbox);
5792
5793       check = gtk_check_button_new_with_label("Editable");
5794       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
5795       gtk_signal_connect (GTK_OBJECT(check), "toggled",
5796                           GTK_SIGNAL_FUNC(text_toggle_editable), text);
5797       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
5798       gtk_widget_show (check);
5799
5800       check = gtk_check_button_new_with_label("Wrap Words");
5801       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5802       gtk_signal_connect (GTK_OBJECT(check), "toggled",
5803                           GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
5804       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
5805       gtk_widget_show (check);
5806
5807       separator = gtk_hseparator_new ();
5808       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5809       gtk_widget_show (separator);
5810
5811
5812       box2 = gtk_vbox_new (FALSE, 10);
5813       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5814       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5815       gtk_widget_show (box2);
5816
5817
5818       button = gtk_button_new_with_label ("insert random");
5819       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5820                           GTK_SIGNAL_FUNC(text_insert_random),
5821                           GTK_TEXT (text));
5822       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5823       gtk_widget_show (button);
5824
5825       button = gtk_button_new_with_label ("close");
5826       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5827                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5828                                  GTK_OBJECT (window));
5829       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5830       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5831       gtk_widget_grab_default (button);
5832       gtk_widget_show (button);
5833     }
5834
5835   if (!GTK_WIDGET_VISIBLE (window))
5836     gtk_widget_show (window);
5837   else
5838     gtk_widget_destroy (window);
5839 }
5840
5841 /*
5842  * GtkNotebook
5843  */
5844
5845 GdkPixmap *book_open;
5846 GdkPixmap *book_closed;
5847 GdkBitmap *book_open_mask;
5848 GdkBitmap *book_closed_mask;
5849 GtkWidget *sample_notebook;
5850
5851 static void
5852 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
5853 {
5854   GtkNotebookPage *oldpage;
5855   GtkWidget *pixwid;
5856
5857   oldpage = GTK_NOTEBOOK (widget)->cur_page;
5858
5859   if (page == oldpage)
5860     return;
5861   pixwid = ((GtkBoxChild*)
5862             (GTK_BOX (page->tab_label)->children->data))->widget;
5863   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
5864   pixwid = ((GtkBoxChild*)
5865             (GTK_BOX (page->menu_label)->children->data))->widget;
5866   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
5867
5868   if (oldpage)
5869     {
5870       pixwid = ((GtkBoxChild*)
5871                 (GTK_BOX (oldpage->tab_label)->children->data))->widget;
5872       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
5873       pixwid = ((GtkBoxChild*)
5874                 (GTK_BOX (oldpage->menu_label)->children->data))->widget;
5875       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
5876     }
5877 }
5878
5879 static void
5880 tab_fill (GtkToggleButton *button, GtkWidget *child)
5881 {
5882   gboolean expand;
5883   GtkPackType pack_type;
5884
5885   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5886                                         &expand, NULL, &pack_type);
5887   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5888                                       expand, button->active, pack_type);
5889 }
5890
5891 static void
5892 tab_expand (GtkToggleButton *button, GtkWidget *child)
5893 {
5894   gboolean fill;
5895   GtkPackType pack_type;
5896
5897   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5898                                         NULL, &fill, &pack_type);
5899   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5900                                       button->active, fill, pack_type);
5901 }
5902
5903 static void
5904 tab_pack (GtkToggleButton *button, GtkWidget *child)
5905           
5906
5907   gboolean expand;
5908   gboolean fill;
5909
5910   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5911                                         &expand, &fill, NULL);
5912   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
5913                                       expand, fill, button->active);
5914 }
5915
5916 static void
5917 create_pages (GtkNotebook *notebook, gint start, gint end)
5918 {
5919   GtkWidget *child = NULL;
5920   GtkWidget *button;
5921   GtkWidget *label;
5922   GtkWidget *hbox;
5923   GtkWidget *vbox;
5924   GtkWidget *label_box;
5925   GtkWidget *menu_box;
5926   GtkWidget *pixwid;
5927   gint i;
5928   char buffer[32];
5929
5930   for (i = start; i <= end; i++)
5931     {
5932       sprintf (buffer, "Page %d", i);
5933
5934       child = gtk_frame_new (buffer);
5935       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
5936
5937       vbox = gtk_vbox_new (TRUE,0);
5938       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
5939       gtk_container_add (GTK_CONTAINER (child), vbox);
5940
5941       hbox = gtk_hbox_new (TRUE,0);
5942       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
5943
5944       button = gtk_check_button_new_with_label ("Fill Tab");
5945       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5946       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
5947       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5948                           GTK_SIGNAL_FUNC (tab_fill), child);
5949
5950       button = gtk_check_button_new_with_label ("Expand Tab");
5951       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5952       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5953       GTK_SIGNAL_FUNC (tab_expand), child);
5954
5955       button = gtk_check_button_new_with_label ("Pack end");
5956       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5957       gtk_signal_connect (GTK_OBJECT (button), "toggled",
5958                           GTK_SIGNAL_FUNC (tab_pack), child);
5959
5960       button = gtk_button_new_with_label ("Hide Page");
5961       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
5962       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5963                                  GTK_SIGNAL_FUNC (gtk_widget_hide),
5964                                  GTK_OBJECT (child));
5965
5966       gtk_widget_show_all (child);
5967
5968       label_box = gtk_hbox_new (FALSE, 0);
5969       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5970       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
5971       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5972       label = gtk_label_new (buffer);
5973       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
5974       gtk_widget_show_all (label_box);
5975
5976       menu_box = gtk_hbox_new (FALSE, 0);
5977       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5978       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
5979       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5980       label = gtk_label_new (buffer);
5981       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
5982       gtk_widget_show_all (menu_box);
5983       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
5984     }
5985 }
5986
5987 static void
5988 rotate_notebook (GtkButton   *button,
5989                  GtkNotebook *notebook)
5990 {
5991   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
5992 }
5993
5994 static void
5995 show_all_pages (GtkButton   *button,
5996                 GtkNotebook *notebook)
5997 {  
5998   gtk_container_foreach (GTK_CONTAINER (notebook),
5999                          (GtkCallback) gtk_widget_show, NULL);
6000 }
6001
6002 static void
6003 standard_notebook (GtkButton   *button,
6004                    GtkNotebook *notebook)
6005 {
6006   gint i;
6007
6008   gtk_notebook_set_show_tabs (notebook, TRUE);
6009   gtk_notebook_set_scrollable (notebook, FALSE);
6010   if (g_list_length (notebook->children) == 15)
6011     for (i = 0; i < 10; i++)
6012       gtk_notebook_remove_page (notebook, 5);
6013 }
6014
6015 static void
6016 notabs_notebook (GtkButton   *button,
6017                  GtkNotebook *notebook)
6018 {
6019   gint i;
6020
6021   gtk_notebook_set_show_tabs (notebook, FALSE);
6022   if (g_list_length (notebook->children) == 15)
6023     for (i = 0; i < 10; i++)
6024       gtk_notebook_remove_page (notebook, 5);
6025 }
6026
6027 static void
6028 scrollable_notebook (GtkButton   *button,
6029                      GtkNotebook *notebook)
6030 {
6031   gtk_notebook_set_show_tabs (notebook, TRUE);
6032   gtk_notebook_set_scrollable (notebook, TRUE);
6033   if (g_list_length (notebook->children) == 5)
6034     create_pages (notebook, 6, 15);
6035 }
6036
6037 static void
6038 notebook_popup (GtkToggleButton *button,
6039                 GtkNotebook     *notebook)
6040 {
6041   if (button->active)
6042     gtk_notebook_popup_enable (notebook);
6043   else
6044     gtk_notebook_popup_disable (notebook);
6045 }
6046
6047 static void
6048 notebook_homogeneous (GtkToggleButton *button,
6049                       GtkNotebook     *notebook)
6050 {
6051   gtk_notebook_set_homogeneous_tabs (notebook, button->active);
6052 }
6053
6054 static void
6055 create_notebook (void)
6056 {
6057   static GtkWidget *window = NULL;
6058   GtkWidget *box1;
6059   GtkWidget *box2;
6060   GtkWidget *button;
6061   GtkWidget *separator;
6062   GtkWidget *omenu;
6063   GdkColor *transparent = NULL;
6064   GtkWidget *label;
6065
6066   static OptionMenuItem items[] =
6067   {
6068     { "Standard",   standard_notebook },
6069     { "No tabs",    notabs_notebook },
6070     { "Scrollable", scrollable_notebook }
6071   };
6072
6073   if (!window)
6074     {
6075       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6076
6077       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6078                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6079                           &window);
6080
6081       gtk_window_set_title (GTK_WINDOW (window), "notebook");
6082       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6083
6084       box1 = gtk_vbox_new (FALSE, 0);
6085       gtk_container_add (GTK_CONTAINER (window), box1);
6086
6087       sample_notebook = gtk_notebook_new ();
6088       gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page",
6089                           GTK_SIGNAL_FUNC (page_switch), NULL);
6090       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6091       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6092       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6093
6094       gtk_widget_realize (sample_notebook);
6095       book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window,
6096                                                 &book_open_mask, 
6097                                                 transparent, 
6098                                                 book_open_xpm);
6099       book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window,
6100                                                   &book_closed_mask,
6101                                                   transparent, 
6102                                                   book_closed_xpm);
6103
6104       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6105
6106       separator = gtk_hseparator_new ();
6107       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6108       
6109       box2 = gtk_hbox_new (FALSE, 5);
6110       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6111       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6112
6113       button = gtk_check_button_new_with_label ("popup menu");
6114       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6115       gtk_signal_connect (GTK_OBJECT(button), "clicked",
6116                           GTK_SIGNAL_FUNC (notebook_popup),
6117                           GTK_OBJECT (sample_notebook));
6118
6119       button = gtk_check_button_new_with_label ("homogeneous tabs");
6120       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6121       gtk_signal_connect (GTK_OBJECT(button), "clicked",
6122                           GTK_SIGNAL_FUNC (notebook_homogeneous),
6123                           GTK_OBJECT (sample_notebook));
6124
6125       box2 = gtk_hbox_new (FALSE, 5);
6126       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6127       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6128
6129       label = gtk_label_new ("Notebook Style :");
6130       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6131
6132       omenu = build_option_menu (items, 3, 0, sample_notebook);
6133       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6134
6135       button = gtk_button_new_with_label ("Show all Pages");
6136       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6137       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6138                           GTK_SIGNAL_FUNC (show_all_pages), sample_notebook);
6139
6140       box2 = gtk_hbox_new (TRUE, 10);
6141       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6142       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6143
6144       button = gtk_button_new_with_label ("prev");
6145       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6146                                  GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
6147                                  GTK_OBJECT (sample_notebook));
6148       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6149
6150       button = gtk_button_new_with_label ("next");
6151       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6152                                  GTK_SIGNAL_FUNC (gtk_notebook_next_page),
6153                                  GTK_OBJECT (sample_notebook));
6154       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6155
6156       button = gtk_button_new_with_label ("rotate");
6157       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6158                           GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook);
6159       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6160
6161       separator = gtk_hseparator_new ();
6162       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6163
6164       button = gtk_button_new_with_label ("close");
6165       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6166       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6167                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
6168                                  GTK_OBJECT (window));
6169       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6170       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6171       gtk_widget_grab_default (button);
6172     }
6173
6174   if (!GTK_WIDGET_VISIBLE (window))
6175     gtk_widget_show_all (window);
6176   else
6177     gtk_widget_destroy (window);
6178 }
6179
6180 /*
6181  * GtkPanes
6182  */
6183
6184 void
6185 toggle_resize (GtkWidget *widget, GtkWidget *child)
6186 {
6187   GtkPaned *paned = GTK_PANED (child->parent);
6188   gboolean is_child1 = (child == paned->child1);
6189   gboolean resize, shrink;
6190
6191   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
6192   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
6193
6194   gtk_widget_ref (child);
6195   gtk_container_remove (GTK_CONTAINER (child->parent), child);
6196   if (is_child1)
6197     gtk_paned_pack1 (paned, child, !resize, shrink);
6198   else
6199     gtk_paned_pack2 (paned, child, !resize, shrink);
6200   gtk_widget_unref (child);
6201 }
6202
6203 void
6204 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6205 {
6206   GtkPaned *paned = GTK_PANED (child->parent);
6207   gboolean is_child1 = (child == paned->child1);
6208   gboolean resize, shrink;
6209
6210   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
6211   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
6212
6213   gtk_widget_ref (child);
6214   gtk_container_remove (GTK_CONTAINER (child->parent), child);
6215   if (is_child1)
6216     gtk_paned_pack1 (paned, child, resize, !shrink);
6217   else
6218     gtk_paned_pack2 (paned, child, resize, !shrink);
6219   gtk_widget_unref (child);
6220 }
6221
6222 GtkWidget *
6223 create_pane_options (GtkPaned *paned,
6224                      const gchar *frame_label,
6225                      const gchar *label1,
6226                      const gchar *label2)
6227 {
6228   GtkWidget *frame;
6229   GtkWidget *table;
6230   GtkWidget *label;
6231   GtkWidget *check_button;
6232   
6233   frame = gtk_frame_new (frame_label);
6234   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6235   
6236   table = gtk_table_new (3, 2, 4);
6237   gtk_container_add (GTK_CONTAINER (frame), table);
6238   
6239   label = gtk_label_new (label1);
6240   gtk_table_attach_defaults (GTK_TABLE (table), label,
6241                              0, 1, 0, 1);
6242   
6243   check_button = gtk_check_button_new_with_label ("Resize");
6244   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6245                              0, 1, 1, 2);
6246   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6247                       GTK_SIGNAL_FUNC (toggle_resize),
6248                       paned->child1);
6249   
6250   check_button = gtk_check_button_new_with_label ("Shrink");
6251   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6252                              0, 1, 2, 3);
6253   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6254                                TRUE);
6255   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6256                       GTK_SIGNAL_FUNC (toggle_shrink),
6257                       paned->child1);
6258   
6259   label = gtk_label_new (label2);
6260   gtk_table_attach_defaults (GTK_TABLE (table), label,
6261                              1, 2, 0, 1);
6262   
6263   check_button = gtk_check_button_new_with_label ("Resize");
6264   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6265                              1, 2, 1, 2);
6266   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6267                                TRUE);
6268   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6269                       GTK_SIGNAL_FUNC (toggle_resize),
6270                       paned->child2);
6271   
6272   check_button = gtk_check_button_new_with_label ("Shrink");
6273   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
6274                              1, 2, 2, 3);
6275   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6276                                TRUE);
6277   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6278                       GTK_SIGNAL_FUNC (toggle_shrink),
6279                       paned->child2);
6280
6281   return frame;
6282 }
6283
6284 void
6285 create_panes (void)
6286 {
6287   static GtkWidget *window = NULL;
6288   GtkWidget *frame;
6289   GtkWidget *hpaned;
6290   GtkWidget *vpaned;
6291   GtkWidget *button;
6292   GtkWidget *vbox;
6293
6294   if (!window)
6295     {
6296       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6297
6298       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6299                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6300                           &window);
6301
6302       gtk_window_set_title (GTK_WINDOW (window), "Panes");
6303       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6304
6305       vbox = gtk_vbox_new (FALSE, 0);
6306       gtk_container_add (GTK_CONTAINER (window), vbox);
6307       
6308       vpaned = gtk_vpaned_new ();
6309       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6310       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6311
6312       hpaned = gtk_hpaned_new ();
6313       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6314
6315       frame = gtk_frame_new (NULL);
6316       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6317       gtk_widget_set_usize (frame, 60, 60);
6318       gtk_paned_add1 (GTK_PANED (hpaned), frame);
6319       
6320       button = gtk_button_new_with_label ("Hi there");
6321       gtk_container_add (GTK_CONTAINER(frame), button);
6322
6323       frame = gtk_frame_new (NULL);
6324       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6325       gtk_widget_set_usize (frame, 80, 60);
6326       gtk_paned_add2 (GTK_PANED (hpaned), frame);
6327
6328       frame = gtk_frame_new (NULL);
6329       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6330       gtk_widget_set_usize (frame, 60, 80);
6331       gtk_paned_add2 (GTK_PANED (vpaned), frame);
6332
6333       /* Now create toggle buttons to control sizing */
6334
6335       gtk_box_pack_start (GTK_BOX (vbox),
6336                           create_pane_options (GTK_PANED (hpaned),
6337                                                "Horizontal",
6338                                                "Left",
6339                                                "Right"),
6340                           FALSE, FALSE, 0);
6341
6342       gtk_box_pack_start (GTK_BOX (vbox),
6343                           create_pane_options (GTK_PANED (vpaned),
6344                                                "Vertical",
6345                                                "Top",
6346                                                "Bottom"),
6347                           FALSE, FALSE, 0);
6348
6349       gtk_widget_show_all (vbox);
6350     }
6351
6352   if (!GTK_WIDGET_VISIBLE (window))
6353     gtk_widget_show (window);
6354   else
6355     gtk_widget_destroy (window);
6356 }
6357
6358 /*
6359  * Drag -N- Drop
6360  */
6361
6362 #if 0
6363 gint
6364 dnd_drop_destroy_popup (GtkWidget *widget, GtkWindow **window)
6365 {
6366   if(GTK_IS_BUTTON(widget)) /* I.e. they clicked the close button */
6367     gtk_widget_destroy(GTK_WIDGET(*window));
6368   else {
6369     gtk_grab_remove(GTK_WIDGET(*window));
6370     *window = NULL;
6371   }
6372
6373   return FALSE;
6374 }
6375
6376 void
6377 dnd_drop (GtkWidget *button, GdkEvent *event)
6378 {
6379   static GtkWidget *window = NULL;
6380   GtkWidget *vbox, *lbl, *btn;
6381   gchar *msg;
6382
6383   /* DND doesn't obey gtk_grab's, so check if we're already displaying
6384    * drop modal dialog first
6385    */
6386   if (window)
6387     return;
6388
6389   window = gtk_window_new(GTK_WINDOW_DIALOG);
6390   gtk_container_set_border_width (GTK_CONTAINER(window), 10);
6391
6392   gtk_signal_connect (GTK_OBJECT (window), "destroy",
6393                       GTK_SIGNAL_FUNC(dnd_drop_destroy_popup),
6394                       &window);
6395   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
6396                       GTK_SIGNAL_FUNC(gtk_false),
6397                       &window);
6398
6399   vbox = gtk_vbox_new(FALSE, 5);
6400
6401   /* Display message that we got from drop source */
6402   msg = g_malloc(strlen(event->dropdataavailable.data)
6403                  + strlen(event->dropdataavailable.data_type) + 100);
6404   sprintf(msg, "Drop data of type %s was:\n\n%s",
6405           event->dropdataavailable.data_type,
6406           (char *)event->dropdataavailable.data);
6407   lbl = gtk_label_new(msg);
6408   gtk_label_set_justify(GTK_LABEL(lbl), GTK_JUSTIFY_FILL);
6409   g_free(msg);
6410   gtk_widget_show(lbl);
6411   gtk_box_pack_start_defaults(GTK_BOX(vbox), lbl);
6412
6413   /* Provide an obvious way out of this heinousness */
6414   btn = gtk_button_new_with_label("Continue with life in\nspite of this oppression");
6415   gtk_signal_connect_object (GTK_OBJECT (btn), "clicked",
6416                              GTK_SIGNAL_FUNC(gtk_widget_destroy),
6417                              GTK_OBJECT (window));
6418   gtk_widget_show(btn);
6419   gtk_box_pack_start_defaults(GTK_BOX(vbox), btn);
6420
6421   gtk_container_add(GTK_CONTAINER(window), vbox);
6422
6423   gtk_widget_show(vbox);
6424   gtk_grab_add(window);
6425   gtk_widget_show(window);
6426 }
6427
6428 void
6429 dnd_drag_request (GtkWidget *button, GdkEvent *event)
6430 {
6431 #define DND_STRING "Bill Gates demands royalties for\nyour use of his innovation."
6432   gtk_widget_dnd_data_set (button, event, DND_STRING, strlen(DND_STRING) + 1);
6433 }
6434
6435 void
6436 create_dnd (void)
6437 {
6438   static GtkWidget *window = NULL;
6439   GtkWidget *box1;
6440   GtkWidget *box2;
6441   GtkWidget *box3;
6442   GtkWidget *frame;
6443   GtkWidget *button;
6444   GtkWidget *separator;
6445
6446   /* For clarity... */
6447   char *possible_drag_types[] = {"text/plain"};
6448   char *accepted_drop_types[] = {"text/plain"};
6449
6450   static GtkWidget *drag_icon = NULL;
6451   static GtkWidget *drop_icon = NULL;
6452
6453   if (!window)
6454     {
6455       GdkPoint hotspot = {5,5};
6456       
6457       if (!drag_icon)
6458         {
6459           drag_icon = shape_create_icon ("Modeller.xpm",
6460                                          440, 140, 0,0, GTK_WINDOW_POPUP);
6461           
6462           gtk_signal_connect (GTK_OBJECT (drag_icon), "destroy",
6463                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6464                               &drag_icon);
6465
6466           gtk_widget_hide (drag_icon);
6467         }
6468       
6469       if (!drop_icon)
6470         {
6471           drop_icon = shape_create_icon ("3DRings.xpm",
6472                                          440, 140, 0,0, GTK_WINDOW_POPUP);
6473           
6474           gtk_signal_connect (GTK_OBJECT (drop_icon), "destroy",
6475                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6476                               &drop_icon);
6477
6478           gtk_widget_hide (drop_icon);
6479         }
6480
6481       gdk_dnd_set_drag_shape(drag_icon->window,
6482                              &hotspot,
6483                              drop_icon->window,
6484                              &hotspot);
6485
6486       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6487
6488       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6489                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6490                           &window);
6491
6492       gtk_window_set_title (GTK_WINDOW (window), "Drag -N- Drop");
6493       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6494
6495       box1 = gtk_vbox_new (FALSE, 0);
6496       gtk_container_add (GTK_CONTAINER (window), box1);
6497       gtk_widget_show (box1);
6498
6499       box2 = gtk_hbox_new (FALSE, 5);
6500       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6501       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
6502       gtk_widget_show (box2);
6503
6504       frame = gtk_frame_new ("Drag");
6505       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
6506       gtk_widget_show (frame);
6507
6508       box3 = gtk_vbox_new (FALSE, 5);
6509       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
6510       gtk_container_add (GTK_CONTAINER (frame), box3);
6511       gtk_widget_show (box3);
6512
6513       /*
6514        * FROM Button
6515        */
6516       button = gtk_button_new_with_label ("Drag me!");
6517       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
6518       gtk_widget_show (button);
6519
6520       /*
6521        * currently, the widget has to be realized to
6522        * set dnd on it, this needs to change
6523        */
6524       gtk_widget_realize (button);
6525       gtk_signal_connect (GTK_OBJECT (button),
6526                           "drag_request_event",
6527                           GTK_SIGNAL_FUNC(dnd_drag_request),
6528                           button);
6529       
6530       gtk_widget_dnd_drag_set (button, TRUE, possible_drag_types, 1);
6531
6532
6533       frame = gtk_frame_new ("Drop");
6534       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
6535       gtk_widget_show (frame);
6536
6537       box3 = gtk_vbox_new (FALSE, 5);
6538       gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
6539       gtk_container_add (GTK_CONTAINER (frame), box3);
6540       gtk_widget_show (box3);
6541
6542
6543       /*
6544        * TO Button
6545        */
6546       button = gtk_button_new_with_label ("To");
6547       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
6548       gtk_widget_show (button);
6549
6550       gtk_widget_realize (button);
6551       gtk_signal_connect (GTK_OBJECT (button), 
6552                           "drop_data_available_event",
6553                           GTK_SIGNAL_FUNC(dnd_drop),
6554                           button);
6555
6556       gtk_widget_dnd_drop_set (button, TRUE, accepted_drop_types, 1, FALSE);
6557
6558
6559       separator = gtk_hseparator_new ();
6560       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6561       gtk_widget_show (separator);
6562
6563
6564       box2 = gtk_vbox_new (FALSE, 10);
6565       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6566       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6567       gtk_widget_show (box2);
6568
6569
6570       button = gtk_button_new_with_label ("close");
6571
6572       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6573                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6574                                  GTK_OBJECT (window));
6575
6576       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6577       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6578       gtk_widget_grab_default (button);
6579       gtk_widget_show (button);
6580     }
6581
6582   if (!GTK_WIDGET_VISIBLE (window))
6583     gtk_widget_show (window);
6584   else
6585     gtk_widget_destroy (window);
6586 }
6587 #endif
6588
6589 /*
6590  * Shaped Windows
6591  */
6592
6593 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6594
6595 static void
6596 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6597 {
6598   CursorOffset *p;
6599
6600   /* ignore double and triple click */
6601   if (event->type != GDK_BUTTON_PRESS)
6602     return;
6603
6604   p = gtk_object_get_user_data (GTK_OBJECT(widget));
6605   p->x = (int) event->x;
6606   p->y = (int) event->y;
6607
6608   gtk_grab_add (widget);
6609   gdk_pointer_grab (widget->window, TRUE,
6610                     GDK_BUTTON_RELEASE_MASK |
6611                     GDK_BUTTON_MOTION_MASK |
6612                     GDK_POINTER_MOTION_HINT_MASK,
6613                     NULL, NULL, 0);
6614 }
6615
6616 static void
6617 shape_released (GtkWidget *widget)
6618 {
6619   gtk_grab_remove (widget);
6620   gdk_pointer_ungrab (0);
6621 }
6622
6623 static void
6624 shape_motion (GtkWidget      *widget, 
6625               GdkEventMotion *event)
6626 {
6627   gint xp, yp;
6628   CursorOffset * p;
6629   GdkModifierType mask;
6630
6631   p = gtk_object_get_user_data (GTK_OBJECT (widget));
6632
6633   /*
6634    * Can't use event->x / event->y here 
6635    * because I need absolute coordinates.
6636    */
6637   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
6638   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
6639 }
6640
6641 GtkWidget *
6642 shape_create_icon (char     *xpm_file,
6643                    gint      x,
6644                    gint      y,
6645                    gint      px,
6646                    gint      py,
6647                    gint      window_type)
6648 {
6649   GtkWidget *window;
6650   GtkWidget *pixmap;
6651   GtkWidget *fixed;
6652   CursorOffset* icon_pos;
6653   GdkGC* gc;
6654   GdkBitmap *gdk_pixmap_mask;
6655   GdkPixmap *gdk_pixmap;
6656   GtkStyle *style;
6657
6658   style = gtk_widget_get_default_style ();
6659   gc = style->black_gc; 
6660
6661   /*
6662    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
6663    */
6664   window = gtk_window_new (window_type);
6665   
6666   fixed = gtk_fixed_new ();
6667   gtk_widget_set_usize (fixed, 100,100);
6668   gtk_container_add (GTK_CONTAINER (window), fixed);
6669   gtk_widget_show (fixed);
6670   
6671   gtk_widget_set_events (window, 
6672                          gtk_widget_get_events (window) |
6673                          GDK_BUTTON_MOTION_MASK |
6674                          GDK_POINTER_MOTION_HINT_MASK |
6675                          GDK_BUTTON_PRESS_MASK);
6676
6677   gtk_widget_realize (window);
6678   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
6679                                            &style->bg[GTK_STATE_NORMAL],
6680                                            xpm_file);
6681
6682   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
6683   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
6684   gtk_widget_show (pixmap);
6685   
6686   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px,py);
6687
6688
6689   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
6690                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
6691   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
6692                       GTK_SIGNAL_FUNC (shape_released),NULL);
6693   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
6694                       GTK_SIGNAL_FUNC (shape_motion),NULL);
6695
6696   icon_pos = g_new (CursorOffset, 1);
6697   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
6698
6699   gtk_widget_set_uposition (window, x, y);
6700   gtk_widget_show (window);
6701   
6702   return window;
6703 }
6704
6705 void 
6706 create_shapes (void)
6707 {
6708   /* Variables used by the Drag/Drop and Shape Window demos */
6709   static GtkWidget *modeller = NULL;
6710   static GtkWidget *sheets = NULL;
6711   static GtkWidget *rings = NULL;
6712
6713   if (!modeller)
6714     {
6715       modeller = shape_create_icon ("Modeller.xpm",
6716                                     440, 140, 0,0, GTK_WINDOW_POPUP);
6717
6718       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
6719                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6720                           &modeller);
6721     }
6722   else
6723     gtk_widget_destroy (modeller);
6724
6725   if (!sheets)
6726     {
6727       sheets = shape_create_icon ("FilesQueue.xpm",
6728                                   580, 170, 0,0, GTK_WINDOW_POPUP);
6729
6730       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
6731                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6732                           &sheets);
6733
6734     }
6735   else
6736     gtk_widget_destroy (sheets);
6737
6738   if (!rings)
6739     {
6740       rings = shape_create_icon ("3DRings.xpm",
6741                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
6742
6743       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
6744                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6745                           &rings);
6746     }
6747   else
6748     gtk_widget_destroy (rings);
6749 }
6750
6751 /*
6752  * WM Hints demo
6753  */
6754
6755 void
6756 create_wmhints (void)
6757 {
6758   static GtkWidget *window = NULL;
6759   GtkWidget *label;
6760   GtkWidget *separator;
6761   GtkWidget *button;
6762   GtkWidget *box1;
6763   GtkWidget *box2;
6764
6765   GdkBitmap *circles;
6766
6767   if (!window)
6768     {
6769       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6770
6771       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6772                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6773                           &window);
6774
6775       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
6776       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6777
6778       gtk_widget_realize (window);
6779       
6780       circles = gdk_bitmap_create_from_data (window->window,
6781                                              circles_bits,
6782                                              circles_width,
6783                                              circles_height);
6784       gdk_window_set_icon (window->window, NULL,
6785                            circles, circles);
6786       
6787       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
6788   
6789       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
6790       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
6791       
6792       box1 = gtk_vbox_new (FALSE, 0);
6793       gtk_container_add (GTK_CONTAINER (window), box1);
6794       gtk_widget_show (box1);
6795
6796       label = gtk_label_new ("Try iconizing me!");
6797       gtk_widget_set_usize (label, 150, 50);
6798       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
6799       gtk_widget_show (label);
6800
6801
6802       separator = gtk_hseparator_new ();
6803       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
6804       gtk_widget_show (separator);
6805
6806
6807       box2 = gtk_vbox_new (FALSE, 10);
6808       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6809       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6810       gtk_widget_show (box2);
6811
6812
6813       button = gtk_button_new_with_label ("close");
6814
6815       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6816                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6817                                  GTK_OBJECT (window));
6818
6819       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6820       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6821       gtk_widget_grab_default (button);
6822       gtk_widget_show (button);
6823     }
6824
6825   if (!GTK_WIDGET_VISIBLE (window))
6826     gtk_widget_show (window);
6827   else
6828     gtk_widget_destroy (window);
6829 }
6830
6831 /*
6832  * GtkProgressBar
6833  */
6834
6835 typedef struct _ProgressData {
6836   GtkWidget *window;
6837   GtkWidget *pbar;
6838   GtkWidget *block_spin;
6839   GtkWidget *x_align_spin;
6840   GtkWidget *y_align_spin;
6841   GtkWidget *step_spin;
6842   GtkWidget *act_blocks_spin;
6843   GtkWidget *label;
6844   GtkWidget *omenu1;
6845   GtkWidget *omenu2;
6846   GtkWidget *entry;
6847   int timer;
6848 } ProgressData;
6849
6850 gint
6851 progress_timeout (gpointer data)
6852 {
6853   gfloat new_val;
6854   GtkAdjustment *adj;
6855
6856   adj = GTK_PROGRESS (data)->adjustment;
6857
6858   new_val = adj->value + 1;
6859   if (new_val > adj->upper)
6860     new_val = adj->lower;
6861
6862   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
6863
6864   return TRUE;
6865 }
6866
6867 static void
6868 destroy_progress (GtkWidget     *widget,
6869                   ProgressData **pdata)
6870 {
6871   gtk_timeout_remove ((*pdata)->timer);
6872   (*pdata)->timer = 0;
6873   (*pdata)->window = NULL;
6874   g_free (*pdata);
6875   *pdata = NULL;
6876 }
6877
6878 static void
6879 progressbar_toggle_orientation (GtkWidget *widget, ProgressData *pdata)
6880 {
6881   gint i;
6882
6883   if (!GTK_WIDGET_MAPPED (widget))
6884     return;
6885
6886   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
6887                     (((GtkOptionMenu *)(pdata->omenu1))->menu_item), i);
6888
6889   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
6890                             (GtkProgressBarOrientation) (3-i));
6891 }
6892
6893 static void
6894 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
6895 {
6896   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
6897                               GTK_TOGGLE_BUTTON (widget)->active);
6898   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
6899   gtk_widget_set_sensitive (pdata->x_align_spin,
6900                             GTK_TOGGLE_BUTTON (widget)->active);
6901   gtk_widget_set_sensitive (pdata->y_align_spin,
6902                             GTK_TOGGLE_BUTTON (widget)->active);
6903 }
6904
6905 static void
6906 progressbar_toggle_bar_style (GtkWidget *widget, ProgressData *pdata)
6907 {
6908   gint i;
6909
6910   if (!GTK_WIDGET_MAPPED (widget))
6911     return;
6912
6913   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
6914                     (((GtkOptionMenu *)(pdata->omenu2))->menu_item), i);
6915
6916   i = 1 - i;
6917
6918   if (i == 1)
6919     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
6920   else
6921     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
6922
6923   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
6924                                   (GtkProgressBarStyle) i);
6925 }
6926
6927 static void
6928 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
6929 {
6930   char buf[20];
6931
6932   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
6933     sprintf (buf, "???");
6934   else
6935     sprintf (buf, "%.0f%%", 100 *
6936              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
6937   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
6938 }
6939
6940 static void
6941 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
6942 {
6943   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
6944   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
6945      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
6946 }
6947
6948 static void
6949 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
6950 {
6951   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
6952      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
6953 }
6954
6955 static void
6956 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
6957 {
6958   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
6959                gtk_spin_button_get_value_as_int 
6960                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
6961 }
6962
6963 static void
6964 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
6965 {
6966   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
6967          gtk_spin_button_get_value_as_float 
6968                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
6969          gtk_spin_button_get_value_as_float
6970                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
6971 }
6972
6973 static void
6974 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
6975 {
6976   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
6977                                   GTK_TOGGLE_BUTTON (widget)->active);
6978   gtk_widget_set_sensitive (pdata->step_spin, 
6979                             GTK_TOGGLE_BUTTON (widget)->active);
6980   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
6981                             GTK_TOGGLE_BUTTON (widget)->active);
6982 }
6983
6984 static void
6985 entry_changed (GtkWidget *widget, ProgressData *pdata)
6986 {
6987   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
6988                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
6989 }
6990
6991 void
6992 create_progress_bar (void)
6993 {
6994   GtkWidget *button;
6995   GtkWidget *vbox;
6996   GtkWidget *vbox2;
6997   GtkWidget *hbox;
6998   GtkWidget *check;
6999   GtkWidget *frame;
7000   GtkWidget *tab;
7001   GtkWidget *label;
7002   GtkWidget *align;
7003   GtkAdjustment *adj;
7004   static ProgressData *pdata = NULL;
7005
7006   static OptionMenuItem items1[] =
7007   {
7008     { "Left-Right", progressbar_toggle_orientation },
7009     { "Right-Left", progressbar_toggle_orientation },
7010     { "Bottom-Top", progressbar_toggle_orientation },
7011     { "Top-Bottom", progressbar_toggle_orientation }
7012   };
7013
7014   static OptionMenuItem items2[] =
7015   {
7016     { "Continuous", progressbar_toggle_bar_style },
7017     { "Discrete",   progressbar_toggle_bar_style }
7018   };
7019
7020   if (!pdata)
7021     pdata = g_new0 (ProgressData, 1);
7022
7023   if (!pdata->window)
7024     {
7025       pdata->window = gtk_dialog_new ();
7026
7027       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
7028
7029       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
7030                           GTK_SIGNAL_FUNC (destroy_progress),
7031                           &pdata);
7032
7033       pdata->timer = 0;
7034
7035       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
7036       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
7037
7038       vbox = gtk_vbox_new (FALSE, 5);
7039       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
7040       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
7041                           vbox, FALSE, TRUE, 0);
7042
7043       frame = gtk_frame_new ("Progress");
7044       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
7045
7046       vbox2 = gtk_vbox_new (FALSE, 5);
7047       gtk_container_add (GTK_CONTAINER (frame), vbox2);
7048
7049       align = gtk_alignment_new (0.5, 0.5, 0, 0);
7050       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
7051
7052       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
7053       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7054                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
7055
7056       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
7057       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
7058                                       "%v from [%l,%u] (=%p%%)");
7059       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
7060       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
7061
7062       align = gtk_alignment_new (0.5, 0.5, 0, 0);
7063       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
7064
7065       hbox = gtk_hbox_new (FALSE, 5);
7066       gtk_container_add (GTK_CONTAINER (align), hbox);
7067       label = gtk_label_new ("Label updated by user :"); 
7068       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7069       pdata->label = gtk_label_new ("");
7070       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
7071
7072       frame = gtk_frame_new ("Options");
7073       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
7074
7075       vbox2 = gtk_vbox_new (FALSE, 5);
7076       gtk_container_add (GTK_CONTAINER (frame), vbox2);
7077
7078       tab = gtk_table_new (7, 2, FALSE);
7079       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
7080
7081       label = gtk_label_new ("Orientation :");
7082       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
7083                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7084                         5, 5);
7085       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7086
7087       pdata->omenu1 = build_option_menu (items1, 4, 0, pdata);
7088       hbox = gtk_hbox_new (FALSE, 0);
7089       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
7090                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7091                         5, 5);
7092       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
7093       
7094       check = gtk_check_button_new_with_label ("Show text");
7095       gtk_signal_connect (GTK_OBJECT (check), "clicked",
7096                           GTK_SIGNAL_FUNC (toggle_show_text),
7097                           pdata);
7098       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
7099                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7100                         5, 5);
7101
7102       hbox = gtk_hbox_new (FALSE, 0);
7103       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
7104                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7105                         5, 5);
7106
7107       label = gtk_label_new ("Format : ");
7108       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7109
7110       pdata->entry = gtk_entry_new ();
7111       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
7112                           GTK_SIGNAL_FUNC (entry_changed),
7113                           pdata);
7114       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
7115       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
7116       gtk_widget_set_usize (pdata->entry, 100, -1);
7117       gtk_widget_set_sensitive (pdata->entry, FALSE);
7118
7119       label = gtk_label_new ("Text align :");
7120       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
7121                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7122                         5, 5);
7123       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7124
7125       hbox = gtk_hbox_new (FALSE, 0);
7126       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
7127                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7128                         5, 5);
7129
7130       label = gtk_label_new ("x :");
7131       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
7132       
7133       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
7134       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
7135       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7136                           GTK_SIGNAL_FUNC (adjust_align), pdata);
7137       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
7138       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
7139
7140       label = gtk_label_new ("y :");
7141       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
7142
7143       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
7144       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
7145       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7146                           GTK_SIGNAL_FUNC (adjust_align), pdata);
7147       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
7148       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
7149
7150       label = gtk_label_new ("Bar Style :");
7151       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
7152                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7153                         5, 5);
7154       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7155
7156       pdata->omenu2 = build_option_menu (items2, 2, 0, pdata);
7157       hbox = gtk_hbox_new (FALSE, 0);
7158       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
7159                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7160                         5, 5);
7161       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
7162
7163       label = gtk_label_new ("Block count :");
7164       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
7165                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7166                         5, 5);
7167       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
7168
7169       hbox = gtk_hbox_new (FALSE, 0);
7170       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
7171                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7172                         5, 5);
7173       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
7174       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
7175       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7176                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
7177       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
7178       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
7179
7180       check = gtk_check_button_new_with_label ("Activity mode");
7181       gtk_signal_connect (GTK_OBJECT (check), "clicked",
7182                           GTK_SIGNAL_FUNC (toggle_activity_mode),
7183                           pdata);
7184       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
7185                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7186                         5, 5);
7187
7188       hbox = gtk_hbox_new (FALSE, 0);
7189       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
7190                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7191                         5, 5);
7192       label = gtk_label_new ("Step size : ");
7193       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7194       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
7195       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
7196       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7197                           GTK_SIGNAL_FUNC (adjust_step), pdata);
7198       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
7199       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
7200
7201       hbox = gtk_hbox_new (FALSE, 0);
7202       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
7203                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
7204                         5, 5);
7205       label = gtk_label_new ("Blocks :     ");
7206       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
7207       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
7208       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
7209       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7210                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
7211       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
7212                           0);
7213       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
7214
7215       button = gtk_button_new_with_label ("close");
7216       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7217                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7218                                  GTK_OBJECT (pdata->window));
7219       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7220       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
7221                           button, TRUE, TRUE, 0);
7222       gtk_widget_grab_default (button);
7223     }
7224
7225   if (!GTK_WIDGET_VISIBLE (pdata->window))
7226     gtk_widget_show_all (pdata->window);
7227   else
7228     gtk_widget_destroy (pdata->window);
7229 }
7230
7231 /*
7232  * Color Preview
7233  */
7234
7235 static int color_idle = 0;
7236
7237 gint
7238 color_idle_func (GtkWidget *preview)
7239 {
7240   static int count = 1;
7241   guchar buf[768];
7242   int i, j, k;
7243
7244   for (i = 0; i < 256; i++)
7245     {
7246       for (j = 0, k = 0; j < 256; j++)
7247         {
7248           buf[k+0] = i + count;
7249           buf[k+1] = 0;
7250           buf[k+2] = j + count;
7251           k += 3;
7252         }
7253
7254       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7255     }
7256
7257   count += 1;
7258
7259   gtk_widget_draw (preview, NULL);
7260
7261   return TRUE;
7262 }
7263
7264 static void
7265 color_preview_destroy (GtkWidget  *widget,
7266                        GtkWidget **window)
7267 {
7268   gtk_idle_remove (color_idle);
7269   color_idle = 0;
7270
7271   *window = NULL;
7272 }
7273
7274 void
7275 create_color_preview (void)
7276 {
7277   static GtkWidget *window = NULL;
7278   GtkWidget *preview;
7279   guchar buf[768];
7280   int i, j, k;
7281
7282   if (!window)
7283     {
7284       gtk_widget_push_visual (gdk_rgb_get_visual ());
7285       gtk_widget_push_colormap (gdk_rgb_get_cmap ());
7286       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7287       gtk_widget_pop_colormap ();
7288       gtk_widget_pop_visual ();
7289
7290       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7291                           GTK_SIGNAL_FUNC(color_preview_destroy),
7292                           &window);
7293
7294       gtk_window_set_title (GTK_WINDOW (window), "test");
7295       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7296
7297       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
7298       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
7299       gtk_container_add (GTK_CONTAINER (window), preview);
7300
7301       for (i = 0; i < 256; i++)
7302         {
7303           for (j = 0, k = 0; j < 256; j++)
7304             {
7305               buf[k+0] = i;
7306               buf[k+1] = 0;
7307               buf[k+2] = j;
7308               k += 3;
7309             }
7310
7311           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7312         }
7313
7314       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
7315     }
7316
7317   if (!GTK_WIDGET_VISIBLE (window))
7318     gtk_widget_show_all (window);
7319   else
7320     gtk_widget_destroy (window);
7321 }
7322
7323 /*
7324  * Gray Preview
7325  */
7326
7327 static int gray_idle = 0;
7328
7329 gint
7330 gray_idle_func (GtkWidget *preview)
7331 {
7332   static int count = 1;
7333   guchar buf[256];
7334   int i, j;
7335
7336   for (i = 0; i < 256; i++)
7337     {
7338       for (j = 0; j < 256; j++)
7339         buf[j] = i + j + count;
7340
7341       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7342     }
7343
7344   count += 1;
7345
7346   gtk_widget_draw (preview, NULL);
7347
7348   return TRUE;
7349 }
7350
7351 static void
7352 gray_preview_destroy (GtkWidget  *widget,
7353                       GtkWidget **window)
7354 {
7355   gtk_idle_remove (gray_idle);
7356   gray_idle = 0;
7357
7358   *window = NULL;
7359 }
7360
7361 void
7362 create_gray_preview (void)
7363 {
7364   static GtkWidget *window = NULL;
7365   GtkWidget *preview;
7366   guchar buf[256];
7367   int i, j;
7368
7369   if (!window)
7370     {
7371       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7372
7373       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7374                           GTK_SIGNAL_FUNC(gray_preview_destroy),
7375                           &window);
7376
7377       gtk_window_set_title (GTK_WINDOW (window), "test");
7378       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7379
7380       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
7381       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
7382       gtk_container_add (GTK_CONTAINER (window), preview);
7383
7384       for (i = 0; i < 256; i++)
7385         {
7386           for (j = 0; j < 256; j++)
7387             buf[j] = i + j;
7388
7389           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
7390         }
7391
7392       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
7393     }
7394
7395   if (!GTK_WIDGET_VISIBLE (window))
7396     gtk_widget_show_all (window);
7397   else
7398     gtk_widget_destroy (window);
7399 }
7400
7401
7402 /*
7403  * Selection Test
7404  */
7405
7406 void
7407 selection_test_received (GtkWidget *list, GtkSelectionData *data)
7408 {
7409   GdkAtom *atoms;
7410   GtkWidget *list_item;
7411   GList *item_list;
7412   int i, l;
7413
7414   if (data->length < 0)
7415     {
7416       g_print ("Selection retrieval failed\n");
7417       return;
7418     }
7419   if (data->type != GDK_SELECTION_TYPE_ATOM)
7420     {
7421       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
7422       return;
7423     }
7424
7425   /* Clear out any current list items */
7426
7427   gtk_list_clear_items (GTK_LIST(list), 0, -1);
7428
7429   /* Add new items to list */
7430
7431   atoms = (GdkAtom *)data->data;
7432
7433   item_list = NULL;
7434   l = data->length / sizeof (GdkAtom);
7435   for (i = 0; i < l; i++)
7436     {
7437       char *name;
7438       name = gdk_atom_name (atoms[i]);
7439       if (name != NULL)
7440         {
7441           list_item = gtk_list_item_new_with_label (name);
7442           g_free (name);
7443         }
7444       else
7445         list_item = gtk_list_item_new_with_label ("(bad atom)");
7446
7447       gtk_widget_show (list_item);
7448       item_list = g_list_append (item_list, list_item);
7449     }
7450
7451   gtk_list_append_items (GTK_LIST (list), item_list);
7452
7453   return;
7454 }
7455
7456 void
7457 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
7458 {
7459   static GdkAtom targets_atom = GDK_NONE;
7460
7461   if (targets_atom == GDK_NONE)
7462     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
7463
7464   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
7465                          GDK_CURRENT_TIME);
7466 }
7467
7468 void
7469 create_selection_test (void)
7470 {
7471   static GtkWidget *window = NULL;
7472   GtkWidget *button;
7473   GtkWidget *vbox;
7474   GtkWidget *scrolled_win;
7475   GtkWidget *list;
7476   GtkWidget *label;
7477
7478   if (!window)
7479     {
7480       window = gtk_dialog_new ();
7481
7482       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7483                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7484                           &window);
7485
7486       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
7487       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7488
7489       /* Create the list */
7490
7491       vbox = gtk_vbox_new (FALSE, 5);
7492       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
7493       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
7494                           TRUE, TRUE, 0);
7495
7496       label = gtk_label_new ("Gets available targets for current selection");
7497       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7498
7499       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
7500       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
7501                                       GTK_POLICY_AUTOMATIC, 
7502                                       GTK_POLICY_AUTOMATIC);
7503       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
7504       gtk_widget_set_usize (scrolled_win, 100, 200);
7505
7506       list = gtk_list_new ();
7507       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
7508
7509       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
7510                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
7511
7512       /* .. And create some buttons */
7513       button = gtk_button_new_with_label ("Get Targets");
7514       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7515                           button, TRUE, TRUE, 0);
7516
7517       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7518                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
7519
7520       button = gtk_button_new_with_label ("Quit");
7521       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7522                           button, TRUE, TRUE, 0);
7523
7524       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7525                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7526                                  GTK_OBJECT (window));
7527     }
7528
7529   if (!GTK_WIDGET_VISIBLE (window))
7530     gtk_widget_show_all (window);
7531   else
7532     gtk_widget_destroy (window);
7533 }
7534
7535 /*
7536  * Gamma Curve
7537  */
7538
7539 void
7540 create_gamma_curve (void)
7541 {
7542   static GtkWidget *window = NULL, *curve;
7543   static int count = 0;
7544   gfloat vec[256];
7545   gint max;
7546   gint i;
7547
7548   if (!window)
7549     {
7550       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7551       gtk_window_set_title (GTK_WINDOW (window), "test");
7552       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
7553
7554       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7555                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7556                           &window);
7557
7558       curve = gtk_gamma_curve_new ();
7559       gtk_container_add (GTK_CONTAINER (window), curve);
7560       gtk_widget_show (curve);
7561     }
7562
7563   max = 127 + (count % 2)*128;
7564   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
7565                        0, max, 0, max);
7566   for (i = 0; i < max; ++i)
7567     vec[i] = (127 / sqrt (max)) * sqrt (i);
7568   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
7569                         max, vec);
7570
7571   if (!GTK_WIDGET_VISIBLE (window))
7572     gtk_widget_show (window);
7573   else if (count % 4 == 3)
7574     {
7575       gtk_widget_destroy (window);
7576       window = NULL;
7577     }
7578
7579   ++count;
7580 }
7581
7582 /*
7583  * Test scrolling
7584  */
7585
7586 static int scroll_test_pos = 0.0;
7587 static GdkGC *scroll_test_gc = NULL;
7588
7589 static gint
7590 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
7591                     GtkAdjustment *adj)
7592 {
7593   gint i,j;
7594   gint imin, imax, jmin, jmax;
7595   
7596   imin = (event->area.x) / 10;
7597   imax = (event->area.x + event->area.width + 9) / 10;
7598
7599   jmin = ((int)adj->value + event->area.y) / 10;
7600   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
7601
7602   gdk_window_clear_area (widget->window,
7603                          event->area.x, event->area.y,
7604                          event->area.width, event->area.height);
7605
7606   for (i=imin; i<imax; i++)
7607     for (j=jmin; j<jmax; j++)
7608       if ((i+j) % 2)
7609         gdk_draw_rectangle (widget->window, 
7610                             widget->style->black_gc,
7611                             TRUE,
7612                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
7613
7614   return TRUE;
7615 }
7616
7617 static gint
7618 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
7619                     GtkAdjustment *adj)
7620 {
7621   gfloat new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
7622                                    -adj->page_increment / 2:
7623                                    adj->page_increment / 2);
7624   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
7625   gtk_adjustment_set_value (adj, new_value);  
7626   
7627   return TRUE;
7628 }
7629
7630 static void
7631 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
7632                        GtkAdjustment *adj)
7633 {
7634   adj->page_increment = 0.9 * widget->allocation.height;
7635   adj->page_size = widget->allocation.height;
7636
7637   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
7638 }
7639
7640 static void
7641 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
7642 {
7643   gint source_min = (int)adj->value - scroll_test_pos;
7644   gint source_max = source_min + widget->allocation.height;
7645   gint dest_min = 0;
7646   gint dest_max = widget->allocation.height;
7647   GdkRectangle rect;
7648   GdkEvent *event;
7649
7650   scroll_test_pos = adj->value;
7651
7652   if (!GTK_WIDGET_DRAWABLE (widget))
7653     return;
7654
7655   if (source_min < 0)
7656     {
7657       rect.x = 0; 
7658       rect.y = 0;
7659       rect.width = widget->allocation.width;
7660       rect.height = -source_min;
7661       if (rect.height > widget->allocation.height)
7662         rect.height = widget->allocation.height;
7663
7664       source_min = 0;
7665       dest_min = rect.height;
7666     }
7667   else
7668     {
7669       rect.x = 0;
7670       rect.y = 2*widget->allocation.height - source_max;
7671       if (rect.y < 0)
7672         rect.y = 0;
7673       rect.width = widget->allocation.width;
7674       rect.height = widget->allocation.height - rect.y;
7675
7676       source_max = widget->allocation.height;
7677       dest_max = rect.y;
7678     }
7679
7680   if (source_min != source_max)
7681     {
7682       if (scroll_test_gc == NULL)
7683         {
7684           scroll_test_gc = gdk_gc_new (widget->window);
7685           gdk_gc_set_exposures (scroll_test_gc, TRUE);
7686         }
7687
7688       gdk_draw_pixmap (widget->window,
7689                        scroll_test_gc,
7690                        widget->window,
7691                        0, source_min,
7692                        0, dest_min,
7693                        widget->allocation.width,
7694                        source_max - source_min);
7695
7696       /* Make sure graphics expose events are processed before scrolling
7697        * again */
7698       
7699       while ((event = gdk_event_get_graphics_expose (widget->window)) != NULL)
7700         {
7701           gtk_widget_event (widget, event);
7702           if (event->expose.count == 0)
7703             {
7704               gdk_event_free (event);
7705               break;
7706             }
7707           gdk_event_free (event);
7708         }
7709     }
7710
7711   if (rect.height != 0)
7712     gtk_widget_draw (widget, &rect);
7713 }
7714
7715
7716 void
7717 create_scroll_test (void)
7718 {
7719   static GtkWidget *window = NULL;
7720   GtkWidget *hbox;
7721   GtkWidget *drawing_area;
7722   GtkWidget *scrollbar;
7723   GtkWidget *button;
7724   GtkAdjustment *adj;
7725   GdkGeometry geometry;
7726   GdkWindowHints geometry_mask;
7727   
7728   if (!window)
7729     {
7730       window = gtk_dialog_new ();
7731
7732       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7733                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7734                           &window);
7735
7736       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
7737       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7738
7739       hbox = gtk_hbox_new (FALSE, 0);
7740       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
7741                           TRUE, TRUE, 0);
7742       gtk_widget_show (hbox);
7743
7744       drawing_area = gtk_drawing_area_new ();
7745       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
7746       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
7747       gtk_widget_show (drawing_area);
7748
7749       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
7750
7751       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
7752       scroll_test_pos = 0.0;
7753
7754       scrollbar = gtk_vscrollbar_new (adj);
7755       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
7756       gtk_widget_show (scrollbar);
7757
7758       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
7759                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
7760       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
7761                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
7762       gtk_signal_connect (GTK_OBJECT (drawing_area), "scroll_event",
7763                           GTK_SIGNAL_FUNC (scroll_test_scroll), adj);
7764       
7765       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
7766                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
7767                           drawing_area);
7768       
7769       /* .. And create some buttons */
7770
7771       button = gtk_button_new_with_label ("Quit");
7772       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
7773                           button, TRUE, TRUE, 0);
7774
7775       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7776                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7777                                  GTK_OBJECT (window));
7778       gtk_widget_show (button);
7779
7780       /* Set up gridded geometry */
7781
7782       geometry_mask = GDK_HINT_MIN_SIZE | 
7783                        GDK_HINT_BASE_SIZE | 
7784                        GDK_HINT_RESIZE_INC;
7785
7786       geometry.min_width = 20;
7787       geometry.min_height = 20;
7788       geometry.base_width = 0;
7789       geometry.base_height = 0;
7790       geometry.width_inc = 10;
7791       geometry.height_inc = 10;
7792       
7793       gtk_window_set_geometry_hints (GTK_WINDOW (window),
7794                                drawing_area, &geometry, geometry_mask);
7795     }
7796
7797   if (!GTK_WIDGET_VISIBLE (window))
7798     gtk_widget_show (window);
7799   else
7800     gtk_widget_destroy (window);
7801 }
7802
7803 /*
7804  * Timeout Test
7805  */
7806
7807 static int timer = 0;
7808
7809 gint
7810 timeout_test (GtkWidget *label)
7811 {
7812   static int count = 0;
7813   static char buffer[32];
7814
7815   sprintf (buffer, "count: %d", ++count);
7816   gtk_label_set_text (GTK_LABEL (label), buffer);
7817
7818   return TRUE;
7819 }
7820
7821 void
7822 start_timeout_test (GtkWidget *widget,
7823                     GtkWidget *label)
7824 {
7825   if (!timer)
7826     {
7827       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
7828     }
7829 }
7830
7831 void
7832 stop_timeout_test (GtkWidget *widget,
7833                    gpointer   data)
7834 {
7835   if (timer)
7836     {
7837       gtk_timeout_remove (timer);
7838       timer = 0;
7839     }
7840 }
7841
7842 void
7843 destroy_timeout_test (GtkWidget  *widget,
7844                       GtkWidget **window)
7845 {
7846   stop_timeout_test (NULL, NULL);
7847
7848   *window = NULL;
7849 }
7850
7851 void
7852 create_timeout_test (void)
7853 {
7854   static GtkWidget *window = NULL;
7855   GtkWidget *button;
7856   GtkWidget *label;
7857
7858   if (!window)
7859     {
7860       window = gtk_dialog_new ();
7861
7862       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7863                           GTK_SIGNAL_FUNC(destroy_timeout_test),
7864                           &window);
7865
7866       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
7867       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7868
7869       label = gtk_label_new ("count: 0");
7870       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
7871       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7872                           label, TRUE, TRUE, 0);
7873       gtk_widget_show (label);
7874
7875       button = gtk_button_new_with_label ("close");
7876       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7877                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7878                                  GTK_OBJECT (window));
7879       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7880       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7881                           button, TRUE, TRUE, 0);
7882       gtk_widget_grab_default (button);
7883       gtk_widget_show (button);
7884
7885       button = gtk_button_new_with_label ("start");
7886       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7887                           GTK_SIGNAL_FUNC(start_timeout_test),
7888                           label);
7889       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7890       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7891                           button, TRUE, TRUE, 0);
7892       gtk_widget_show (button);
7893
7894       button = gtk_button_new_with_label ("stop");
7895       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7896                           GTK_SIGNAL_FUNC(stop_timeout_test),
7897                           NULL);
7898       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7899       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7900                           button, TRUE, TRUE, 0);
7901       gtk_widget_show (button);
7902     }
7903
7904   if (!GTK_WIDGET_VISIBLE (window))
7905     gtk_widget_show (window);
7906   else
7907     gtk_widget_destroy (window);
7908 }
7909
7910 /*
7911  * Idle Test
7912  */
7913
7914 static int idle_id = 0;
7915
7916 static gint
7917 idle_test (GtkWidget *label)
7918 {
7919   static int count = 0;
7920   static char buffer[32];
7921
7922   sprintf (buffer, "count: %d", ++count);
7923   gtk_label_set_text (GTK_LABEL (label), buffer);
7924
7925   return TRUE;
7926 }
7927
7928 static void
7929 start_idle_test (GtkWidget *widget,
7930                  GtkWidget *label)
7931 {
7932   if (!idle_id)
7933     {
7934       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
7935     }
7936 }
7937
7938 static void
7939 stop_idle_test (GtkWidget *widget,
7940                 gpointer   data)
7941 {
7942   if (idle_id)
7943     {
7944       gtk_idle_remove (idle_id);
7945       idle_id = 0;
7946     }
7947 }
7948
7949 static void
7950 destroy_idle_test (GtkWidget  *widget,
7951                    GtkWidget **window)
7952 {
7953   stop_idle_test (NULL, NULL);
7954
7955   *window = NULL;
7956 }
7957
7958 static void
7959 toggle_idle_container (GtkObject *button,
7960                        GtkContainer *container)
7961 {
7962   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (gtk_object_get_user_data (button)));
7963 }
7964
7965 static void
7966 create_idle_test (void)
7967 {
7968   static GtkWidget *window = NULL;
7969   GtkWidget *button;
7970   GtkWidget *label;
7971   GtkWidget *container;
7972
7973   if (!window)
7974     {
7975       GtkWidget *frame;
7976       GtkWidget *box;
7977
7978       window = gtk_dialog_new ();
7979
7980       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7981                           GTK_SIGNAL_FUNC(destroy_idle_test),
7982                           &window);
7983
7984       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
7985       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7986
7987       label = gtk_label_new ("count: 0");
7988       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
7989       gtk_widget_show (label);
7990       
7991       container =
7992         gtk_widget_new (GTK_TYPE_HBOX,
7993                         "GtkWidget::visible", TRUE,
7994                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
7995                          * "GtkWidget::visible", TRUE,
7996                          */
7997                          "GtkContainer::child", label,
7998                         /* NULL), */
7999                         NULL);
8000       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
8001                           container, TRUE, TRUE, 0);
8002
8003       frame =
8004         gtk_widget_new (GTK_TYPE_FRAME,
8005                         "GtkContainer::border_width", 5,
8006                         "GtkFrame::label", "Label Container",
8007                         "GtkWidget::visible", TRUE,
8008                         "GtkWidget::parent", GTK_DIALOG (window)->vbox,
8009                         NULL);
8010       box =
8011         gtk_widget_new (GTK_TYPE_VBOX,
8012                         "GtkWidget::visible", TRUE,
8013                         "GtkWidget::parent", frame,
8014                         NULL);
8015       button =
8016         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
8017                         "GtkButton::label", "Resize-Parent",
8018                         "GtkObject::user_data", (void*)GTK_RESIZE_PARENT,
8019                         "GtkObject::signal::clicked", toggle_idle_container, container,
8020                         "GtkWidget::visible", TRUE,
8021                         "GtkWidget::parent", box,
8022                         NULL);
8023       button =
8024         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
8025                         "GtkButton::label", "Resize-Queue",
8026                         "GtkObject::user_data", (void*)GTK_RESIZE_QUEUE,
8027                         "GtkObject::signal::clicked", toggle_idle_container, container,
8028                         "GtkRadioButton::group", button,
8029                         "GtkWidget::visible", TRUE,
8030                         "GtkWidget::parent", box,
8031                         NULL);
8032       button =
8033         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
8034                         "GtkButton::label", "Resize-Immediate",
8035                         "GtkObject::user_data", (void*)GTK_RESIZE_IMMEDIATE,
8036                         "GtkObject::signal::clicked", toggle_idle_container, container,
8037                         "GtkRadioButton::group", button,
8038                         "GtkWidget::visible", TRUE,
8039                         "GtkWidget::parent", box,
8040                         NULL);
8041       
8042
8043       button = gtk_button_new_with_label ("close");
8044       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8045                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8046                                  GTK_OBJECT (window));
8047       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8048       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8049                           button, TRUE, TRUE, 0);
8050       gtk_widget_grab_default (button);
8051       gtk_widget_show (button);
8052
8053       button = gtk_button_new_with_label ("start");
8054       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8055                           GTK_SIGNAL_FUNC(start_idle_test),
8056                           label);
8057       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8058       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8059                           button, TRUE, TRUE, 0);
8060       gtk_widget_show (button);
8061
8062       button = gtk_button_new_with_label ("stop");
8063       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8064                           GTK_SIGNAL_FUNC(stop_idle_test),
8065                           NULL);
8066       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8067       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8068                           button, TRUE, TRUE, 0);
8069       gtk_widget_show (button);
8070     }
8071
8072   if (!GTK_WIDGET_VISIBLE (window))
8073     gtk_widget_show (window);
8074   else
8075     gtk_widget_destroy (window);
8076 }
8077
8078 /*
8079  * rc file test
8080  */
8081
8082 void
8083 reload_rc_file (void)
8084 {
8085   GList *toplevels;
8086
8087   if (gtk_rc_reparse_all ())
8088     {
8089       toplevels = gdk_window_get_toplevels();
8090       while (toplevels)
8091         {
8092           GtkWidget *widget;
8093           gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
8094           
8095           if (widget)
8096             gtk_widget_reset_rc_styles (widget);
8097           
8098           toplevels = toplevels->next;
8099         }
8100       g_list_free (toplevels);
8101     }
8102 }
8103
8104 void
8105 reload_all_rc_files (void)
8106 {
8107   static GdkAtom atom_rcfiles = GDK_NONE;
8108
8109   GdkEventClient sev;
8110   int i;
8111   
8112   if (!atom_rcfiles)
8113     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
8114
8115   for(i = 0; i < 5; i++)
8116     sev.data.l[i] = 0;
8117   sev.data_format = 32;
8118   sev.message_type = atom_rcfiles;
8119   gdk_event_send_clientmessage_toall ((GdkEvent *) &sev);
8120 }
8121
8122 void
8123 create_rc_file (void)
8124 {
8125   static GtkWidget *window = NULL;
8126   GtkWidget *button;
8127
8128   if (!window)
8129     {
8130       window = gtk_dialog_new ();
8131
8132       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8133                           GTK_SIGNAL_FUNC(destroy_idle_test),
8134                           &window);
8135
8136       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
8137       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8138
8139       button = gtk_button_new_with_label ("Reload");
8140       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8141                           GTK_SIGNAL_FUNC(reload_rc_file), NULL);
8142       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8143       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8144                           button, TRUE, TRUE, 0);
8145       gtk_widget_grab_default (button);
8146       gtk_widget_show (button);
8147
8148       button = gtk_button_new_with_label ("Reload All");
8149       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8150                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
8151       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8152       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8153                           button, TRUE, TRUE, 0);
8154       gtk_widget_show (button);
8155
8156       button = gtk_button_new_with_label ("Close");
8157       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8158                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8159                                  GTK_OBJECT (window));
8160       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8161       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
8162                           button, TRUE, TRUE, 0);
8163       gtk_widget_show (button);
8164
8165     }
8166
8167   if (!GTK_WIDGET_VISIBLE (window))
8168     gtk_widget_show (window);
8169   else
8170     gtk_widget_destroy (window);
8171 }
8172
8173 /*
8174  * Test of recursive mainloop
8175  */
8176
8177 void
8178 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
8179 {
8180   *window = NULL;
8181   gtk_main_quit ();
8182 }
8183
8184 void
8185 create_mainloop (void)
8186 {
8187   static GtkWidget *window = NULL;
8188   GtkWidget *label;
8189   GtkWidget *button;
8190
8191   if (!window)
8192     {
8193       window = gtk_dialog_new ();
8194
8195       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
8196
8197       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8198                           GTK_SIGNAL_FUNC(mainloop_destroyed),
8199                           &window);
8200
8201       label = gtk_label_new ("In recursive main loop...");
8202       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
8203
8204       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
8205                           TRUE, TRUE, 0);
8206       gtk_widget_show (label);
8207
8208       button = gtk_button_new_with_label ("Leave");
8209       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
8210                           FALSE, TRUE, 0);
8211
8212       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8213                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
8214                                  GTK_OBJECT (window));
8215
8216       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8217       gtk_widget_grab_default (button);
8218
8219       gtk_widget_show (button);
8220     }
8221
8222   if (!GTK_WIDGET_VISIBLE (window))
8223     {
8224       gtk_widget_show (window);
8225
8226       g_print ("create_mainloop: start\n");
8227       gtk_main ();
8228       g_print ("create_mainloop: done\n");
8229     }
8230   else
8231     gtk_widget_destroy (window);
8232 }
8233
8234 gint
8235 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
8236 {
8237   GtkLayout *layout;
8238
8239   gint i,j;
8240   gint imin, imax, jmin, jmax;
8241   
8242   layout = GTK_LAYOUT (widget);
8243
8244   imin = (layout->xoffset + event->area.x) / 10;
8245   imax = (layout->xoffset + event->area.x + event->area.width + 9) / 10;
8246
8247   jmin = (layout->yoffset + event->area.y) / 10;
8248   jmax = (layout->yoffset + event->area.y + event->area.height + 9) / 10;
8249
8250   gdk_window_clear_area (widget->window,
8251                          event->area.x, event->area.y,
8252                          event->area.width, event->area.height);
8253
8254   for (i=imin; i<imax; i++)
8255     for (j=jmin; j<jmax; j++)
8256       if ((i+j) % 2)
8257         gdk_draw_rectangle (layout->bin_window,
8258                             widget->style->black_gc,
8259                             TRUE,
8260                             10*i - layout->xoffset, 10*j - layout->yoffset, 
8261                             1+i%10, 1+j%10);
8262   
8263   return TRUE;
8264 }
8265
8266 void create_layout (void)
8267 {
8268   static GtkWidget *window = NULL;
8269   GtkWidget *layout;
8270   GtkWidget *scrolledwindow;
8271   GtkWidget *button;
8272
8273   if (!window)
8274     {
8275       gchar buf[16];
8276
8277       gint i, j;
8278       
8279       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8280       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8281                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8282                           &window);
8283
8284       gtk_window_set_title (GTK_WINDOW (window), "Layout");
8285       gtk_widget_set_usize (window, 200, 200);
8286
8287       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
8288
8289       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
8290       
8291       layout = gtk_layout_new (NULL, NULL);
8292       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
8293
8294       /* We set step sizes here since GtkLayout does not set
8295        * them itself.
8296        */
8297       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
8298       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
8299       
8300       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
8301       gtk_signal_connect (GTK_OBJECT (layout), "expose_event",
8302                           GTK_SIGNAL_FUNC (layout_expose_handler), NULL);
8303       
8304       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
8305       
8306       for (i=0 ; i < 16 ; i++)
8307         for (j=0 ; j < 16 ; j++)
8308           {
8309             sprintf(buf, "Button %d, %d", i, j);
8310             if ((i + j) % 2)
8311               button = gtk_button_new_with_label (buf);
8312             else
8313               button = gtk_label_new (buf);
8314
8315             gtk_layout_put (GTK_LAYOUT (layout), button,
8316                             j*100, i*100);
8317           }
8318
8319       for (i=16; i < 1280; i++)
8320         {
8321           sprintf(buf, "Button %d, %d", i, 0);
8322           if (i % 2)
8323             button = gtk_button_new_with_label (buf);
8324           else
8325             button = gtk_label_new (buf);
8326
8327           gtk_layout_put (GTK_LAYOUT (layout), button,
8328                           0, i*100);
8329         }
8330     }
8331
8332   if (!GTK_WIDGET_VISIBLE (window))
8333     gtk_widget_show_all (window);
8334   else
8335     gtk_widget_destroy (window);
8336 }
8337
8338 /*
8339  * Main Window and Exit
8340  */
8341
8342 void
8343 do_exit (GtkWidget *widget, GtkWidget *window)
8344 {
8345   gtk_widget_destroy (window);
8346   gtk_main_quit ();
8347 }
8348
8349 void
8350 create_main_window (void)
8351 {
8352   struct {
8353     char *label;
8354     void (*func) ();
8355   } buttons[] =
8356     {
8357       { "button box", create_button_box },
8358       { "buttons", create_buttons },
8359       { "check buttons", create_check_buttons },
8360       { "clist", create_clist},
8361       { "color selection", create_color_selection },
8362       { "ctree", create_ctree },
8363       { "cursors", create_cursors },
8364       { "dialog", create_dialog },
8365       /*      { "dnd", create_dnd }, */
8366       { "entry", create_entry },
8367       { "event watcher", create_event_watcher },
8368       { "file selection", create_file_selection },
8369       { "font selection", create_font_selection },
8370       { "gamma curve", create_gamma_curve },
8371       { "handle box", create_handle_box },
8372       { "item factory", create_item_factory },
8373       { "labels", create_labels },
8374       { "layout", create_layout },
8375       { "list", create_list },
8376       { "menus", create_menus },
8377       { "modal window", create_modal_window },
8378       { "notebook", create_notebook },
8379       { "panes", create_panes },
8380       { "pixmap", create_pixmap },
8381       { "preview color", create_color_preview },
8382       { "preview gray", create_gray_preview },
8383       { "progress bar", create_progress_bar },
8384       { "radio buttons", create_radio_buttons },
8385       { "range controls", create_range_controls },
8386       { "rc file", create_rc_file },
8387       { "reparent", create_reparent },
8388       { "rulers", create_rulers },
8389       { "saved position", create_saved_position },
8390       { "scrolled windows", create_scrolled_windows },
8391       { "shapes", create_shapes },
8392       { "spinbutton", create_spins },
8393       { "statusbar", create_statusbar },
8394       { "test idle", create_idle_test },
8395       { "test mainloop", create_mainloop },
8396       { "test scrolling", create_scroll_test },
8397       { "test selection", create_selection_test },
8398       { "test timeout", create_timeout_test },
8399       { "text", create_text },
8400       { "toggle buttons", create_toggle_buttons },
8401       { "toolbar", create_toolbar },
8402       { "tooltips", create_tooltips },
8403       { "tree", create_tree_mode_window},
8404       { "WM hints", create_wmhints },
8405     };
8406   int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
8407   GtkWidget *window;
8408   GtkWidget *box1;
8409   GtkWidget *box2;
8410   GtkWidget *scrolled_window;
8411   GtkWidget *button;
8412   GtkWidget *label;
8413   gchar buffer[64];
8414   GtkWidget *separator;
8415   int i;
8416
8417   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8418   gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
8419   gtk_widget_set_name (window, "main window");
8420   gtk_widget_set_usize (window, 200, 400);
8421   gtk_widget_set_uposition (window, 20, 20);
8422
8423   gtk_signal_connect (GTK_OBJECT (window), "destroy",
8424                       GTK_SIGNAL_FUNC(gtk_main_quit),
8425                       NULL);
8426   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
8427                       GTK_SIGNAL_FUNC (gtk_false),
8428                       NULL);
8429
8430   box1 = gtk_vbox_new (FALSE, 0);
8431   gtk_container_add (GTK_CONTAINER (window), box1);
8432
8433   if (gtk_micro_version > 0)
8434     sprintf (buffer,
8435              "Gtk+ v%d.%d.%d",
8436              gtk_major_version,
8437              gtk_minor_version,
8438              gtk_micro_version);
8439   else
8440     sprintf (buffer,
8441              "Gtk+ v%d.%d",
8442              gtk_major_version,
8443              gtk_minor_version);
8444
8445   label = gtk_label_new (buffer);
8446   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
8447
8448   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
8449   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
8450   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
8451                                   GTK_POLICY_AUTOMATIC, 
8452                                   GTK_POLICY_AUTOMATIC);
8453   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
8454
8455   box2 = gtk_vbox_new (FALSE, 0);
8456   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8457   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
8458   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
8459                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
8460   gtk_widget_show (box2);
8461
8462   for (i = 0; i < nbuttons; i++)
8463     {
8464       button = gtk_button_new_with_label (buttons[i].label);
8465       if (buttons[i].func)
8466         gtk_signal_connect (GTK_OBJECT (button), 
8467                             "clicked", 
8468                             GTK_SIGNAL_FUNC(buttons[i].func),
8469                             NULL);
8470       else
8471         gtk_widget_set_sensitive (button, FALSE);
8472       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8473     }
8474
8475   separator = gtk_hseparator_new ();
8476   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
8477
8478   box2 = gtk_vbox_new (FALSE, 10);
8479   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8480   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8481
8482   button = gtk_button_new_with_label ("close");
8483   gtk_signal_connect (GTK_OBJECT (button), "clicked",
8484                       GTK_SIGNAL_FUNC (do_exit),
8485                       window);
8486   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8487   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8488   gtk_widget_grab_default (button);
8489
8490   gtk_widget_show_all (window);
8491 }
8492
8493 int
8494 main (int argc, char *argv[])
8495 {
8496   GtkBindingSet *binding_set;
8497   struct stat statbuf;
8498
8499   srand (time (NULL));
8500
8501   gtk_set_locale ();
8502
8503   /* Check to see if we are being run from the correct
8504    * directory.
8505    */
8506   if (stat("./testgtkrc", &statbuf) < 0)
8507     {
8508       fprintf (stderr, "*** The testgtk program must be run from within the\n"
8509                        "*** gtk/ subdirectory of the GTK+ distribution.\n");
8510       exit (1);
8511     }
8512
8513   gtk_rc_add_default_file ("testgtkrc");
8514
8515   gtk_init (&argc, &argv);
8516
8517   gdk_rgb_init ();
8518
8519   /* bindings test
8520    */
8521   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
8522   gtk_binding_entry_add_signal (binding_set,
8523                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
8524                                 "debug_msg",
8525                                 1,
8526                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
8527
8528   create_main_window ();
8529
8530   gtk_main ();
8531
8532   return 0;
8533 }