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