]> Pileus Git - ~andy/gtk/blob - gtk/testgtk.c
Few fixes for column resize. Store resize column in clist->drag_pos.
[~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", 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   gtk_clist_thaw (GTK_CLIST (data));
3158
3159   gdk_pixmap_unref (pixmap);
3160   gdk_bitmap_unref (mask);
3161 }
3162
3163 static void
3164 add10000_clist (GtkWidget *widget, gpointer data)
3165 {
3166   gint i;
3167   char text[TESTGTK_CLIST_COLUMNS][50];
3168   char *texts[TESTGTK_CLIST_COLUMNS];
3169
3170   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3171     {
3172       texts[i] = text[i];
3173       sprintf (text[i], "Column %d", i);
3174     }
3175   
3176   sprintf (text[1], "Right");
3177   sprintf (text[2], "Center");
3178   
3179   gtk_clist_freeze (GTK_CLIST (data));
3180   for (i = 0; i < 10000; i++)
3181     {
3182       sprintf (text[0], "Row %d", clist_rows++);
3183       gtk_clist_append (GTK_CLIST (data), texts);
3184     }
3185   gtk_clist_thaw (GTK_CLIST (data));
3186 }
3187
3188 void
3189 clear_clist (GtkWidget *widget, gpointer data)
3190 {
3191   gtk_clist_clear (GTK_CLIST (data));
3192   clist_rows = 0;
3193 }
3194
3195 void
3196 remove_row_clist (GtkWidget *widget, gpointer data)
3197 {
3198   gtk_clist_remove (GTK_CLIST (data), GTK_CLIST (data)->focus_row);
3199   clist_rows--;
3200 }
3201
3202 void
3203 show_titles_clist (GtkWidget *widget, gpointer data)
3204 {
3205   gtk_clist_column_titles_show (GTK_CLIST (data));
3206 }
3207
3208 void
3209 hide_titles_clist (GtkWidget *widget, gpointer data)
3210 {
3211   gtk_clist_column_titles_hide (GTK_CLIST (data));
3212 }
3213
3214 void
3215 select_clist (GtkWidget *widget,
3216               gint row, 
3217               gint column, 
3218               GdkEventButton * bevent,
3219               GtkWidget *button)
3220 {
3221   gint i;
3222   guint8 spacing;
3223   gchar *text;
3224   GdkPixmap *pixmap;
3225   GdkBitmap *mask;
3226   GList *list;
3227
3228   g_print ("GtkCList Selection: row %d column %d button %d\n", 
3229            row, column, bevent ? bevent->button : 0);
3230
3231   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3232     {
3233       switch (gtk_clist_get_cell_type (GTK_CLIST (widget), row, i))
3234         {
3235         case GTK_CELL_TEXT:
3236           g_print ("CELL %d GTK_CELL_TEXT\n", i);
3237           gtk_clist_get_text (GTK_CLIST (widget), row, i, &text);
3238           g_print ("TEXT: %s\n", text);
3239           break;
3240
3241         case GTK_CELL_PIXMAP:
3242           g_print ("CELL %d GTK_CELL_PIXMAP\n", i);
3243           gtk_clist_get_pixmap (GTK_CLIST (widget), row, i, &pixmap, &mask);
3244           g_print ("PIXMAP: %p\n", pixmap);
3245           g_print ("MASK: %p\n", mask);
3246           break;
3247
3248         case GTK_CELL_PIXTEXT:
3249           g_print ("CELL %d GTK_CELL_PIXTEXT\n", i);
3250           gtk_clist_get_pixtext (GTK_CLIST (widget), row, i, &text, &spacing, &pixmap, &mask);
3251           g_print ("TEXT: %s\n", text);
3252           g_print ("SPACING: %d\n", spacing);
3253           g_print ("PIXMAP: %p\n", pixmap);
3254           g_print ("MASK: %p\n", mask);
3255           break;
3256
3257         default:
3258           break;
3259         }
3260     }
3261
3262   /* print selections list */
3263   g_print ("\nSelected Rows:");
3264   list = GTK_CLIST (widget)->selection;
3265   while (list)
3266     {
3267       g_print (" %d ", GPOINTER_TO_INT (list->data));
3268       list = list->next;
3269     }
3270
3271   g_print ("\n\n\n");
3272 }
3273
3274 void
3275 unselect_clist (GtkWidget *widget,
3276                 gint row, 
3277                 gint column, 
3278                 GdkEventButton * bevent,
3279                 GtkWidget *button)
3280 {
3281   gint i;
3282   guint8 spacing;
3283   gchar *text;
3284   GdkPixmap *pixmap;
3285   GdkBitmap *mask;
3286   GList *list;
3287
3288   g_print ("GtkCList Unselection: row %d column %d button %d\n", 
3289            row, column, bevent ? bevent->button : 0);
3290
3291   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3292     {
3293       switch (gtk_clist_get_cell_type (GTK_CLIST (widget), row, i))
3294         {
3295         case GTK_CELL_TEXT:
3296           g_print ("CELL %d GTK_CELL_TEXT\n", i);
3297           gtk_clist_get_text (GTK_CLIST (widget), row, i, &text);
3298           g_print ("TEXT: %s\n", text);
3299           break;
3300
3301         case GTK_CELL_PIXMAP:
3302           g_print ("CELL %d GTK_CELL_PIXMAP\n", i);
3303           gtk_clist_get_pixmap (GTK_CLIST (widget), row, i, &pixmap, &mask);
3304           g_print ("PIXMAP: %p\n", pixmap);
3305           g_print ("MASK: %p\n", mask);
3306           break;
3307
3308         case GTK_CELL_PIXTEXT:
3309           g_print ("CELL %d GTK_CELL_PIXTEXT\n", i);
3310           gtk_clist_get_pixtext (GTK_CLIST (widget), row, i, &text, &spacing, &pixmap, &mask);
3311           g_print ("TEXT: %s\n", text);
3312           g_print ("SPACING: %d\n", spacing);
3313           g_print ("PIXMAP: %p\n", pixmap);
3314           g_print ("MASK: %p\n", mask);
3315           break;
3316
3317         default:
3318           break;
3319         }
3320     }
3321
3322   /* print selections list */
3323   g_print ("\nSelected Rows:");
3324   list = GTK_CLIST (widget)->selection;
3325   while (list)
3326     {
3327       g_print (" %d ", GPOINTER_TO_INT (list->data));
3328       list = list->next;
3329     }
3330
3331   g_print ("\n\n\n");
3332 }
3333
3334 static void
3335 insert_row_clist (GtkWidget *widget, gpointer data)
3336 {
3337   static char *text[] =
3338   {
3339     "This", "is", "a", "inserted", "row.",
3340     "This", "is", "a", "inserted", "row.",
3341     "This", "is", "a", "inserted", "row.",
3342     "This", "is", "a", "inserted", "row."
3343   };
3344
3345   gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
3346
3347   clist_rows++;
3348 }
3349
3350 static void
3351 clist_warning_test (GtkWidget *button,
3352                     GtkWidget *clist)
3353 {
3354   GtkWidget *child;
3355   static gboolean add_remove = FALSE;
3356
3357   add_remove = !add_remove;
3358
3359   child = gtk_label_new ("Test");
3360   gtk_widget_ref (child);
3361   gtk_object_sink (GTK_OBJECT (child));
3362
3363   if (add_remove)
3364     gtk_container_add (GTK_CONTAINER (clist), child);
3365   else
3366     {
3367       child->parent = clist;
3368       gtk_container_remove (GTK_CONTAINER (clist), child);
3369       child->parent = NULL;
3370     }
3371
3372   gtk_widget_destroy (child);
3373   gtk_widget_unref (child);
3374 }
3375
3376 static void
3377 undo_selection (GtkWidget *button, GtkCList *clist)
3378 {
3379   gtk_clist_undo_selection (clist);
3380 }
3381
3382 static void 
3383 clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
3384 {
3385   gint i;
3386
3387   if (!GTK_WIDGET_MAPPED (widget))
3388     return;
3389
3390   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3391                     (((GtkOptionMenu *)clist_omenu)->menu_item), i);
3392
3393   gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
3394 }
3395
3396 static void
3397 create_clist (void)
3398 {
3399   gint i;
3400   static GtkWidget *window = NULL;
3401
3402   static char *titles[] =
3403   {
3404     "Title 0",  "Title 1",  "Title 2",  "Title 3",  "Title 4",
3405     "Title 5",  "Title 6",  "Title 7",  "Title 8",  "Title 9",
3406     "Title 10", "Title 11", "Title 12", "Title 13", "Title 14",
3407     "Title 15", "Title 16", "Title 17", "Title 18", "Title 19"
3408   };
3409
3410   static OptionMenuItem items[] =
3411   {
3412     { "Single",   clist_toggle_sel_mode },
3413     { "Browse",   clist_toggle_sel_mode },
3414     { "Multiple", clist_toggle_sel_mode },
3415     { "Extended", clist_toggle_sel_mode }
3416   };
3417
3418   char text[TESTGTK_CLIST_COLUMNS][50];
3419   char *texts[TESTGTK_CLIST_COLUMNS];
3420
3421   GtkWidget *box1;
3422   GtkWidget *box2;
3423   GtkWidget *clist;
3424   GtkWidget *button;
3425   GtkWidget *separator;
3426
3427   GtkWidget *undo_button;
3428   GtkWidget *label;
3429
3430   if (!window)
3431     {
3432       clist_rows = 0;
3433       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3434
3435       gtk_signal_connect (GTK_OBJECT (window), "destroy",
3436                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
3437                           &window);
3438
3439       gtk_window_set_title (GTK_WINDOW (window), "clist");
3440       gtk_container_border_width (GTK_CONTAINER (window), 0);
3441
3442       box1 = gtk_vbox_new (FALSE, 0);
3443       gtk_container_add (GTK_CONTAINER (window), box1);
3444
3445       box2 = gtk_hbox_new (FALSE, 10);
3446       gtk_container_border_width (GTK_CONTAINER (box2), 10);
3447       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
3448
3449       /* create GtkCList here so we have a pointer to throw at the 
3450        * button callbacks -- more is done with it later */
3451       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
3452       /*clist = gtk_clist_new (TESTGTK_CLIST_COLUMNS);*/
3453
3454       /* control buttons */
3455       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
3456       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3457
3458       gtk_signal_connect (GTK_OBJECT (button),
3459                           "clicked",
3460                           (GtkSignalFunc) add1000_clist,
3461                           (gpointer) clist);
3462
3463       button = gtk_button_new_with_label ("Add 10,000 Rows");
3464       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3465
3466       gtk_signal_connect (GTK_OBJECT (button),
3467                           "clicked",
3468                           (GtkSignalFunc) add10000_clist,
3469                           (gpointer) clist);
3470
3471       button = gtk_button_new_with_label ("Clear List");
3472       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3473
3474       gtk_signal_connect (GTK_OBJECT (button),
3475                           "clicked",
3476                           (GtkSignalFunc) clear_clist,
3477                           (gpointer) clist);
3478
3479       button = gtk_button_new_with_label ("Remove Row");
3480       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3481
3482       gtk_signal_connect (GTK_OBJECT (button),
3483                           "clicked",
3484                           (GtkSignalFunc) remove_row_clist,
3485                           (gpointer) clist);
3486
3487       /* second layer of buttons */
3488       box2 = gtk_hbox_new (FALSE, 10);
3489       gtk_container_border_width (GTK_CONTAINER (box2), 10);
3490       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
3491
3492       button = gtk_button_new_with_label ("Insert Row");
3493       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3494
3495       gtk_signal_connect (GTK_OBJECT (button),
3496                           "clicked",
3497                           (GtkSignalFunc) insert_row_clist,
3498                           (gpointer) clist);
3499
3500       button = gtk_button_new_with_label ("Show Title Buttons");
3501       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3502
3503       gtk_signal_connect (GTK_OBJECT (button),
3504                           "clicked",
3505                           (GtkSignalFunc) show_titles_clist,
3506                           (gpointer) clist);
3507
3508       button = gtk_button_new_with_label ("Hide Title Buttons");
3509       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3510
3511       gtk_signal_connect (GTK_OBJECT (button),
3512                           "clicked",
3513                           (GtkSignalFunc) hide_titles_clist,
3514                           (gpointer) clist);
3515
3516       button = gtk_button_new_with_label ("Warning Test");
3517       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3518
3519       gtk_signal_connect (GTK_OBJECT (button),
3520                           "clicked",
3521                           (GtkSignalFunc) clist_warning_test,
3522                           (gpointer) clist);
3523
3524       box2 = gtk_hbox_new (FALSE, 10);
3525       gtk_container_border_width (GTK_CONTAINER (box2), 10);
3526       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
3527
3528       undo_button = gtk_button_new_with_label ("Undo last selection");
3529       gtk_box_pack_start (GTK_BOX (box2), undo_button, TRUE, TRUE, 0);
3530       gtk_signal_connect (GTK_OBJECT (undo_button),
3531                           "clicked",
3532                           (GtkSignalFunc) undo_selection,
3533                           (gpointer) clist);
3534
3535       label = gtk_label_new ("Selection Mode :");
3536       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
3537
3538       clist_omenu = build_option_menu (items, 4, 3, clist);
3539       gtk_box_pack_start (GTK_BOX (box2), clist_omenu, FALSE, TRUE, 0);
3540
3541       /* vbox for the list itself */
3542       box2 = gtk_vbox_new (FALSE, 10);
3543       gtk_container_border_width (GTK_CONTAINER (box2), 10);
3544       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3545
3546       /* 
3547        * the rest of the clist configuration
3548        */
3549
3550       /*
3551       gtk_signal_connect (GTK_OBJECT (clist), 
3552                           "select_row",
3553                           (GtkSignalFunc) select_clist, 
3554                           undo_button);
3555
3556       gtk_signal_connect (GTK_OBJECT (clist), 
3557                           "unselect_row",
3558                           (GtkSignalFunc) unselect_clist, 
3559                           undo_button);
3560       */
3561
3562       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
3563       gtk_widget_set_usize (clist, -1, 300);
3564
3565       gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);
3566
3567       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
3568         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
3569
3570       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
3571       gtk_clist_set_policy (GTK_CLIST (clist), GTK_POLICY_AUTOMATIC,
3572                             GTK_POLICY_AUTOMATIC);
3573
3574       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
3575                                           GTK_JUSTIFY_RIGHT);
3576       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
3577                                           GTK_JUSTIFY_CENTER);
3578       
3579       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
3580         {
3581           texts[i] = text[i];
3582           sprintf (text[i], "Column %d", i);
3583         }
3584
3585       sprintf (text[1], "Right");
3586       sprintf (text[2], "Center");
3587
3588       for (i = 0; i < 10; i++)
3589         {
3590           sprintf (text[0], "Row %d", clist_rows++);
3591           gtk_clist_append (GTK_CLIST (clist), texts);
3592         }
3593
3594       gtk_container_border_width (GTK_CONTAINER (clist), 5);
3595       gtk_box_pack_start (GTK_BOX (box2), clist, TRUE, TRUE, 0);
3596
3597       separator = gtk_hseparator_new ();
3598       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3599
3600       box2 = gtk_vbox_new (FALSE, 10);
3601       gtk_container_border_width (GTK_CONTAINER (box2), 10);
3602       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3603
3604       button = gtk_button_new_with_label ("close");
3605       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
3606                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
3607                                  GTK_OBJECT (window));
3608
3609       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3610       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
3611       gtk_widget_grab_default (button);
3612     }
3613
3614   if (!GTK_WIDGET_VISIBLE (window))
3615     gtk_widget_show_all (window);
3616   else
3617     {
3618       clist_rows = 0;
3619       gtk_widget_destroy (window);
3620     }
3621 }
3622
3623 /*
3624  * GtkCTree
3625  */
3626
3627 GdkPixmap *pixmap1;
3628 GdkPixmap *pixmap2;
3629 GdkPixmap *pixmap3;
3630 GdkBitmap *mask1;
3631 GdkBitmap *mask2;
3632 GdkBitmap *mask3;
3633
3634 static gint books = 0;
3635 static gint pages = 0;
3636
3637 static GtkWidget *book_label;
3638 static GtkWidget *page_label;
3639 static GtkWidget *sel_label;
3640 static GtkWidget *vis_label;
3641 static GtkWidget *omenu1;
3642 static GtkWidget *omenu2;
3643 static GtkWidget *omenu3;
3644 static GtkWidget *spin1;
3645 static GtkWidget *spin2;
3646 static GtkWidget *spin3;
3647 static GdkColor  *col_bg;
3648
3649 void after_press (GtkCTree *ctree, gpointer data)
3650 {
3651   char buf[80];
3652
3653   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
3654   gtk_label_set (GTK_LABEL (sel_label), buf);
3655
3656   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
3657   gtk_label_set (GTK_LABEL (vis_label), buf);
3658
3659   sprintf (buf, "%d", books);
3660   gtk_label_set (GTK_LABEL (book_label), buf);
3661
3662   sprintf (buf, "%d", pages);
3663   gtk_label_set (GTK_LABEL (page_label), buf);
3664 }
3665
3666 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
3667                  GtkCTreeNode *sibling, gpointer data)
3668 {
3669   char *source;
3670   char *target1;
3671   char *target2;
3672
3673   gtk_ctree_get_node_info (ctree, child, &source, 
3674                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3675   if (parent)
3676     gtk_ctree_get_node_info (ctree, parent, &target1, 
3677                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3678   if (sibling)
3679     gtk_ctree_get_node_info (ctree, sibling, &target2, 
3680                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
3681
3682   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
3683            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
3684 }
3685
3686 gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
3687 {
3688   gint row;
3689   gint column;
3690   GtkCTreeNode *work;
3691   gint res;
3692   
3693   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
3694                                       &row, &column);
3695   if (!res && event->button != 3)
3696     return FALSE;
3697
3698   work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
3699
3700   switch (event->button)
3701     {
3702     case 1:
3703       if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
3704           event->state & GDK_SHIFT_MASK)
3705         gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),"button_press_event");
3706       break;
3707     case  2:
3708       if (GTK_CTREE_ROW (work)->children && 
3709           gtk_ctree_is_hot_spot (ctree, event->x, event->y))
3710         {
3711           if (GTK_CTREE_ROW (work)->expanded)
3712             gtk_ctree_collapse_recursive (ctree, work);
3713           else
3714             gtk_ctree_expand_recursive (ctree, work);
3715           after_press (ctree, NULL);
3716           gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
3717                                         "button_press_event");
3718         }
3719       break;
3720     default:
3721       break;
3722     }
3723   return FALSE;
3724 }
3725
3726 gint button_release (GtkCTree *ctree, GdkEventButton *event, gpointer data)
3727 {
3728   gint row;
3729   gint column;
3730   GtkCTreeNode *work;
3731   gint res;
3732   
3733   res = gtk_clist_get_selection_info (GTK_CLIST (ctree), event->x, event->y, 
3734                                       &row, &column);
3735   if (!res || event->button != 1)
3736     return FALSE;
3737
3738   work = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list, row));
3739
3740   if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_MULTIPLE &&
3741       event->state & GDK_SHIFT_MASK)
3742     {
3743       if (GTK_CTREE_ROW (work)->row.state == GTK_STATE_SELECTED) 
3744             gtk_ctree_unselect_recursive (ctree, work);
3745       else
3746         gtk_ctree_select_recursive (ctree, work);
3747       after_press (ctree, NULL);
3748       gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree), 
3749                                     "button_release_event");
3750     }
3751   return FALSE;
3752 }
3753
3754 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
3755 {
3756   if (GTK_CTREE_ROW (list)->is_leaf)
3757     pages--;
3758   else
3759     books--;
3760 }
3761
3762 void expand_all (GtkWidget *widget, GtkCTree *ctree)
3763 {
3764   gtk_ctree_expand_recursive (ctree, NULL);
3765   after_press (ctree, NULL);
3766 }
3767
3768 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
3769 {
3770   gtk_ctree_collapse_recursive (ctree, NULL);
3771   after_press (ctree, NULL);
3772 }
3773
3774 void select_all (GtkWidget *widget, GtkCTree *ctree)
3775 {
3776   gtk_ctree_select_recursive (ctree, NULL);
3777   after_press (ctree, NULL);
3778 }
3779
3780 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
3781 {
3782   gtk_ctree_unselect_recursive (ctree, NULL);
3783   after_press (ctree, NULL);
3784 }
3785
3786 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
3787 {
3788   GtkCTreeNode *work;
3789   GtkCTreeNode *new_sel;
3790   GList *selection;
3791
3792   selection = GTK_CLIST (ctree)->selection;
3793   new_sel = NULL;
3794
3795   gtk_clist_freeze (GTK_CLIST (ctree));
3796
3797   while (selection)
3798     {
3799       work = selection->data;
3800       if (GTK_CTREE_ROW (work)->is_leaf)
3801         pages--;
3802       else
3803         gtk_ctree_post_recursive (ctree, work, 
3804                                   (GtkCTreeFunc) count_items, NULL);
3805
3806       if (GTK_CLIST (ctree)->selection_mode == GTK_SELECTION_BROWSE)
3807         {
3808           if (GTK_CTREE_ROW (work)->children)
3809             {
3810               new_sel = GTK_CTREE_ROW (work)->sibling;
3811               if (!new_sel)
3812                 new_sel = GTK_CTREE_NODE_NEXT (work);
3813             }
3814           else
3815             {
3816               if (GTK_CTREE_NODE_NEXT (work))
3817                 new_sel = GTK_CTREE_NODE_NEXT (work);
3818               else
3819                 new_sel = GTK_CTREE_NODE_PREV (work);
3820             }
3821         }
3822
3823       gtk_ctree_remove (ctree, work);
3824       selection = GTK_CLIST (ctree)->selection;
3825     }
3826
3827   if (new_sel)
3828     gtk_ctree_select (ctree, new_sel);
3829
3830   gtk_clist_thaw (GTK_CLIST (ctree));
3831   after_press (ctree, NULL);
3832 }
3833
3834 void sort_all (GtkWidget *widget, GtkCTree *ctree)
3835 {
3836   gtk_ctree_sort_recursive (ctree, NULL);
3837 }
3838
3839 void change_indent (GtkWidget *widget, GtkCTree *ctree)
3840 {
3841   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
3842 }
3843
3844 void change_row_height (GtkWidget *widget, GtkCList *clist)
3845 {
3846   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
3847 }
3848
3849 void toggle_reorderable (GtkWidget *widget, GtkCTree *ctree)
3850 {
3851   gtk_ctree_set_reorderable (ctree, GTK_TOGGLE_BUTTON (widget)->active);
3852 }
3853
3854 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
3855 {
3856   if (!node)
3857     return;
3858   
3859   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
3860     {
3861       if (GTK_CTREE_ROW (node)->is_leaf)
3862         {
3863           if (GTK_CTREE_ROW (node)->parent)
3864             gtk_ctree_set_background 
3865               (ctree, node,
3866                GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data);
3867         }
3868       else
3869        gtk_ctree_set_background (ctree, node, GTK_CTREE_ROW (node)->row.data);
3870     }
3871   else
3872     gtk_ctree_set_background (ctree, node, NULL);
3873 }
3874
3875 void ctree_toggle_line_style (GtkWidget *widget, GtkCTree *ctree)
3876 {
3877   gint i;
3878
3879   if (!GTK_WIDGET_MAPPED (widget))
3880     return;
3881
3882   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3883                     (((GtkOptionMenu *)omenu1)->menu_item),i);
3884   
3885   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
3886        ((GtkCTreeLineStyle) (3-i)) != GTK_CTREE_LINES_TABBED) ||
3887       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
3888        ((GtkCTreeLineStyle) (3-i)) == GTK_CTREE_LINES_TABBED))
3889     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
3890   gtk_ctree_set_line_style (ctree, (GtkCTreeLineStyle) (3-i));
3891 }
3892
3893 void ctree_toggle_justify (GtkWidget *widget, GtkCTree *ctree)
3894 {
3895   gint i;
3896
3897   if (!GTK_WIDGET_MAPPED (widget))
3898     return;
3899
3900   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3901                     (((GtkOptionMenu *)omenu2)->menu_item),i);
3902
3903   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
3904                                       (GtkJustification) (1-i));
3905 }
3906
3907 void ctree_toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
3908 {
3909   gint i;
3910
3911   if (!GTK_WIDGET_MAPPED (widget))
3912     return;
3913
3914   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
3915                     (((GtkOptionMenu *)omenu3)->menu_item), i);
3916
3917   gtk_clist_set_selection_mode (GTK_CLIST (ctree), (GtkSelectionMode) (3-i));
3918   after_press (ctree, NULL);
3919 }
3920
3921 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
3922                       gint num_books, gint num_pages, GtkCTreeNode *parent)
3923 {
3924   gchar *text[2];
3925   gchar buf1[60];
3926   gchar buf2[60];
3927   GtkCTreeNode *sibling;
3928   gint i;
3929
3930   text[0] = buf1;
3931   text[1] = buf2;
3932   sibling = NULL;
3933
3934   for (i = num_pages + num_books; i > num_books; i--)
3935     {
3936       pages++;
3937       sprintf (buf1, "Page %02d", (gint) rand() % 100);
3938       sprintf (buf2, "Item %d-%d", cur_depth, i);
3939       sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap3,
3940                                   mask3, NULL, NULL, TRUE, FALSE);
3941
3942       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
3943         gtk_ctree_set_background (ctree, sibling, col_bg);
3944     }
3945
3946   if (cur_depth == depth)
3947     return;
3948
3949   for (i = num_books; i > 0; i--)
3950     {
3951       books++;
3952       sprintf (buf1, "Book %02d", (gint) rand() % 100);
3953       sprintf (buf2, "Item %d-%d", cur_depth, i);
3954       sibling = gtk_ctree_insert (ctree, parent, sibling, text, 5, pixmap1,
3955                                   mask1, pixmap2, mask2, FALSE, FALSE);
3956
3957       col_bg = g_new (GdkColor, 1);
3958
3959       if (cur_depth % 3 == 0)
3960         {
3961           col_bg->red   = 10000 * (cur_depth % 6);
3962           col_bg->green = 0;
3963           col_bg->blue  = 65535 - ((i * 10000) % 65535);
3964         }
3965       else if (cur_depth % 3 == 1)
3966         {
3967           col_bg->red   = 10000 * (cur_depth % 6);
3968           col_bg->green = 65535 - ((i * 10000) % 65535);
3969           col_bg->blue  = 0;
3970         }
3971       else
3972         {
3973           col_bg->red   = 65535 - ((i * 10000) % 65535);
3974           col_bg->green = 0;
3975           col_bg->blue  = 10000 * (cur_depth % 6);
3976         }
3977         
3978       gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), col_bg);
3979       gtk_ctree_set_row_data_full (ctree, sibling, col_bg, g_free);
3980
3981       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
3982         gtk_ctree_set_background (ctree, sibling, col_bg);
3983
3984       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
3985                        sibling);
3986     }
3987 }
3988
3989 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
3990 {
3991   gchar *text [2];
3992   gchar label1[] = "Root";
3993   gchar label2[] = "";
3994   GtkCTreeNode *parent;
3995   guint b, d, p, n;
3996
3997   text[0] = label1;
3998   text[1] = label2;
3999   
4000   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
4001   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
4002   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
4003
4004   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
4005
4006   if (n > 100000)
4007     {
4008       g_print ("%d total items? Try less\n",n);
4009       return;
4010     }
4011
4012   gtk_clist_freeze (GTK_CLIST (ctree));
4013   gtk_clist_clear (GTK_CLIST (ctree));
4014
4015   books = 1;
4016   pages = 0;
4017
4018   parent = gtk_ctree_insert (ctree, NULL, NULL, text, 5, pixmap1,
4019                              mask1, pixmap2, mask2, FALSE, TRUE);
4020
4021   col_bg = g_new (GdkColor, 1);
4022   col_bg->red   = 0;
4023   col_bg->green = 45000;
4024   col_bg->blue  = 55000;
4025   gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), col_bg);
4026   gtk_ctree_set_row_data_full (ctree, parent, col_bg, g_free);
4027   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
4028     gtk_ctree_set_background (ctree, parent, col_bg);
4029
4030   build_recursive (ctree, 1, d, b, p, parent);
4031   gtk_clist_thaw (GTK_CLIST (ctree));
4032   after_press (ctree, NULL);
4033 }
4034
4035 void create_ctree (void)
4036 {
4037   static GtkWidget *window = NULL;
4038   GtkTooltips *tooltips;
4039   GtkCTree *ctree;
4040   GtkWidget *vbox;
4041   GtkWidget *hbox;
4042   GtkWidget *hbox2;
4043   GtkWidget *frame;
4044   GtkWidget *label;
4045   GtkWidget *button;
4046   GtkWidget *check;
4047   GtkAdjustment *adj;
4048   GtkWidget *spinner;
4049   GdkColor transparent;
4050
4051   char *title[] = { "Tree" , "Info" };
4052   char buf[80];
4053
4054   static OptionMenuItem items1[] =
4055   {
4056     { "Solid",    ctree_toggle_line_style },
4057     { "Dotted",   ctree_toggle_line_style },
4058     { "Tabbed",   ctree_toggle_line_style },
4059     { "No lines", ctree_toggle_line_style }
4060   };
4061
4062   static OptionMenuItem items2[] =
4063   {
4064     { "Left",  ctree_toggle_justify },
4065     { "Right", ctree_toggle_justify }
4066   };
4067
4068   static OptionMenuItem items3[] =
4069   {
4070     { "Single",   ctree_toggle_sel_mode },
4071     { "Browse",   ctree_toggle_sel_mode },
4072     { "Multiple", ctree_toggle_sel_mode },
4073     { "Extended", ctree_toggle_sel_mode }
4074   };
4075
4076   if (!window)
4077     {
4078       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4079
4080       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4081                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4082                           &window);
4083
4084       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
4085       gtk_container_border_width (GTK_CONTAINER (window), 0);
4086
4087       tooltips = gtk_tooltips_new ();
4088       gtk_object_ref (GTK_OBJECT (tooltips));
4089       gtk_object_sink (GTK_OBJECT (tooltips));
4090
4091       gtk_object_set_data_full (GTK_OBJECT (window), "tooltips", tooltips,
4092                                 (GtkDestroyNotify) gtk_object_unref);
4093
4094       vbox = gtk_vbox_new (FALSE, 0);
4095       gtk_container_add (GTK_CONTAINER (window), vbox);
4096
4097       hbox = gtk_hbox_new (FALSE, 5);
4098       gtk_container_border_width (GTK_CONTAINER (hbox), 5);
4099       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4100       
4101       label = gtk_label_new ("Depth :");
4102       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4103       
4104       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
4105       spin1 = gtk_spin_button_new (adj, 0, 0);
4106       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
4107   
4108       label = gtk_label_new ("Books :");
4109       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4110       
4111       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
4112       spin2 = gtk_spin_button_new (adj, 0, 0);
4113       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
4114
4115       label = gtk_label_new ("Pages :");
4116       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4117       
4118       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
4119       spin3 = gtk_spin_button_new (adj, 0, 0);
4120       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
4121
4122       button = gtk_button_new_with_label ("Close");
4123       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4124
4125       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4126                                  (GtkSignalFunc) gtk_widget_destroy,
4127                                  GTK_OBJECT(window));
4128
4129       button = gtk_button_new_with_label ("Rebuild tree");
4130       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4131       
4132       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
4133       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
4134       gtk_ctree_set_reorderable (ctree, TRUE);
4135       gtk_signal_connect (GTK_OBJECT (ctree), "button_press_event",
4136                           GTK_SIGNAL_FUNC (button_press), NULL);
4137       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
4138                                 GTK_SIGNAL_FUNC (after_press), NULL);
4139       gtk_signal_connect (GTK_OBJECT (ctree), "button_release_event",
4140                           GTK_SIGNAL_FUNC (button_release), NULL);
4141       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
4142                                 GTK_SIGNAL_FUNC (after_press), NULL);
4143       gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
4144                                 GTK_SIGNAL_FUNC (after_move), NULL);
4145       gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
4146                                 GTK_SIGNAL_FUNC (after_press), NULL);
4147       gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
4148                                 GTK_SIGNAL_FUNC (after_press), NULL);
4149       gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
4150                                 GTK_SIGNAL_FUNC (after_press), NULL);
4151       gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
4152                                 GTK_SIGNAL_FUNC (after_press), NULL);
4153       gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
4154                                 GTK_SIGNAL_FUNC (after_press), NULL);
4155       
4156       gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
4157       gtk_clist_column_titles_passive (GTK_CLIST (ctree));
4158       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
4159       gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS, 
4160                             GTK_POLICY_AUTOMATIC);
4161       gtk_clist_set_column_width (GTK_CLIST (ctree), 0, 200);
4162       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
4163
4164       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4165                           GTK_SIGNAL_FUNC (rebuild_tree), ctree);
4166       
4167       hbox = gtk_hbox_new (FALSE, 5);
4168       gtk_container_border_width (GTK_CONTAINER (hbox), 5);
4169       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4170
4171       button = gtk_button_new_with_label ("Expand all");
4172       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4173                           GTK_SIGNAL_FUNC (expand_all), ctree);
4174       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4175
4176       button = gtk_button_new_with_label ("Collapse all");
4177       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4178                           GTK_SIGNAL_FUNC (collapse_all), ctree);
4179       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4180
4181       button = gtk_button_new_with_label ("Sort tree");
4182       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4183                           GTK_SIGNAL_FUNC (sort_all), ctree);
4184       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4185
4186       hbox = gtk_hbox_new (FALSE, 5);
4187       gtk_container_border_width (GTK_CONTAINER (hbox), 5);
4188       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4189
4190       label = gtk_label_new ("Row height :");
4191       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
4192       
4193       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
4194       spinner = gtk_spin_button_new (adj, 0, 0);
4195       gtk_tooltips_set_tip (tooltips, spinner,
4196                             "Row height of list items", NULL);
4197       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4198                           GTK_SIGNAL_FUNC (change_row_height), ctree);
4199       gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, TRUE, 5);
4200       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
4201
4202       button = gtk_button_new_with_label ("Select all");
4203       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4204                           GTK_SIGNAL_FUNC (select_all), ctree);
4205       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4206
4207       button = gtk_button_new_with_label ("Unselect all");
4208       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4209                           GTK_SIGNAL_FUNC (unselect_all), ctree);
4210       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4211
4212       button = gtk_button_new_with_label ("Remove selection");
4213       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4214                           GTK_SIGNAL_FUNC (remove_selection), ctree);
4215       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
4216
4217       hbox = gtk_hbox_new (TRUE, 5);
4218       gtk_container_border_width (GTK_CONTAINER (hbox), 5);
4219       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
4220       
4221       hbox2 = gtk_hbox_new (FALSE, 0);
4222       gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, TRUE, 0);
4223       
4224       label = gtk_label_new ("Indent :");
4225       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
4226       
4227       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
4228       spinner = gtk_spin_button_new (adj, 0, 0);
4229       gtk_tooltips_set_tip (tooltips, spinner, "Tree indentation.", NULL);
4230       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
4231                           GTK_SIGNAL_FUNC (change_indent), ctree);
4232       gtk_box_pack_start (GTK_BOX (hbox2), spinner, FALSE, TRUE, 5);
4233       
4234       check = gtk_check_button_new_with_label ("Reorderable");
4235       gtk_tooltips_set_tip (tooltips, check,
4236                             "Tree items can be reordered by dragging.", NULL);
4237       gtk_signal_connect (GTK_OBJECT (check), "clicked",
4238                           GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
4239       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
4240       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (check), TRUE);
4241       
4242       omenu1 = build_option_menu (items1, 4, 1, ctree);
4243       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
4244       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
4245       
4246       omenu2 = build_option_menu (items2, 2, 0, ctree);
4247       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's justification.",
4248                             NULL);
4249       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
4250       
4251       omenu3 = build_option_menu (items3, 4, 3, ctree);
4252       gtk_tooltips_set_tip (tooltips, omenu3, "The list's selection mode.",
4253                             NULL);
4254       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
4255       
4256       gtk_widget_realize (window);
4257       
4258       pixmap1 = gdk_pixmap_create_from_xpm_d (window->window, &mask1, 
4259                                               &transparent, book_closed_xpm);
4260       pixmap2 = gdk_pixmap_create_from_xpm_d (window->window, &mask2, 
4261                                               &transparent, book_open_xpm);
4262       pixmap3 = gdk_pixmap_create_from_xpm_d (window->window, &mask3,
4263                                               &transparent, mini_page_xpm);
4264       
4265       gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
4266       
4267       frame = gtk_frame_new (NULL);
4268       gtk_container_border_width (GTK_CONTAINER (frame), 0);
4269       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
4270       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
4271       
4272       hbox = gtk_hbox_new (TRUE, 2);
4273       gtk_container_border_width (GTK_CONTAINER (hbox), 2);
4274       gtk_container_add (GTK_CONTAINER (frame), hbox);
4275       
4276       frame = gtk_frame_new (NULL);
4277       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
4278       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
4279       
4280       hbox2 = gtk_hbox_new (FALSE, 0);
4281       gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
4282       gtk_container_add (GTK_CONTAINER (frame), hbox2);
4283       
4284       label = gtk_label_new ("Books :");
4285       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
4286       
4287       sprintf (buf, "%d", books);
4288       book_label = gtk_label_new (buf);
4289       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
4290       
4291       frame = gtk_frame_new (NULL);
4292       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
4293       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
4294       
4295       hbox2 = gtk_hbox_new (FALSE, 0);
4296       gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
4297       gtk_container_add (GTK_CONTAINER (frame), hbox2);
4298       
4299       label = gtk_label_new ("Pages :");
4300       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
4301       
4302       sprintf (buf, "%d", pages);
4303       page_label = gtk_label_new (buf);
4304       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
4305       
4306       frame = gtk_frame_new (NULL);
4307       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
4308       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
4309       
4310       hbox2 = gtk_hbox_new (FALSE, 0);
4311       gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
4312       gtk_container_add (GTK_CONTAINER (frame), hbox2);
4313       
4314       label = gtk_label_new ("Selected :");
4315       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
4316       
4317       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
4318       sel_label = gtk_label_new (buf);
4319       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
4320       
4321       frame = gtk_frame_new (NULL);
4322       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
4323       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
4324       
4325       hbox2 = gtk_hbox_new (FALSE, 0);
4326       gtk_container_border_width (GTK_CONTAINER (hbox2), 2);
4327       gtk_container_add (GTK_CONTAINER (frame), hbox2);
4328       
4329       label = gtk_label_new ("Visible :");
4330       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
4331       
4332       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
4333       vis_label = gtk_label_new (buf);
4334       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
4335
4336       rebuild_tree (NULL, ctree);
4337     }
4338
4339   if (!GTK_WIDGET_VISIBLE (window))
4340     gtk_widget_show_all (window);
4341   else
4342     gtk_widget_destroy (window);
4343 }
4344
4345 /*
4346  * GtkColorSelection
4347  */
4348
4349 void
4350 color_selection_ok (GtkWidget               *w,
4351                     GtkColorSelectionDialog *cs)
4352 {
4353   GtkColorSelection *colorsel;
4354   gdouble color[4];
4355
4356   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
4357
4358   gtk_color_selection_get_color(colorsel,color);
4359   gtk_color_selection_set_color(colorsel,color);
4360 }
4361
4362 void
4363 color_selection_changed (GtkWidget *w,
4364                          GtkColorSelectionDialog *cs)
4365 {
4366   GtkColorSelection *colorsel;
4367   gdouble color[4];
4368
4369   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
4370   gtk_color_selection_get_color(colorsel,color);
4371 }
4372
4373 void
4374 create_color_selection (void)
4375 {
4376   static GtkWidget *window = NULL;
4377
4378   if (!window)
4379     {
4380       window = gtk_color_selection_dialog_new ("color selection dialog");
4381
4382       gtk_color_selection_set_opacity (
4383         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
4384         TRUE);
4385
4386       gtk_color_selection_set_update_policy(
4387         GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
4388         GTK_UPDATE_CONTINUOUS);
4389
4390       gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
4391
4392       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4393                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4394                           &window);
4395
4396       gtk_signal_connect (
4397         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
4398         "color_changed",
4399         GTK_SIGNAL_FUNC(color_selection_changed),
4400         window);
4401
4402       gtk_signal_connect (
4403         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
4404         "clicked",
4405         GTK_SIGNAL_FUNC(color_selection_ok),
4406         window);
4407
4408       gtk_signal_connect_object (
4409         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
4410         "clicked",
4411         GTK_SIGNAL_FUNC(gtk_widget_destroy),
4412         GTK_OBJECT (window));
4413     }
4414
4415   if (!GTK_WIDGET_VISIBLE (window))
4416     gtk_widget_show (window);
4417   else
4418     gtk_widget_destroy (window);
4419 }
4420
4421 /*
4422  * GtkFileSelection
4423  */
4424
4425 void
4426 file_selection_hide_fileops (GtkWidget *widget,
4427                              GtkFileSelection *fs)
4428 {
4429   gtk_file_selection_hide_fileop_buttons (fs);
4430 }
4431
4432 void
4433 file_selection_ok (GtkWidget        *w,
4434                    GtkFileSelection *fs)
4435 {
4436   g_print ("%s\n", gtk_file_selection_get_filename (fs));
4437   gtk_widget_destroy (GTK_WIDGET (fs));
4438 }
4439
4440 void
4441 create_file_selection (void)
4442 {
4443   static GtkWidget *window = NULL;
4444   GtkWidget *button;
4445
4446   if (!window)
4447     {
4448       window = gtk_file_selection_new ("file selection dialog");
4449
4450       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
4451
4452       gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
4453
4454       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4455                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4456                           &window);
4457
4458       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (window)->ok_button),
4459                           "clicked", GTK_SIGNAL_FUNC(file_selection_ok),
4460                           window);
4461       gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (window)->cancel_button),
4462                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
4463                                  GTK_OBJECT (window));
4464       
4465       button = gtk_button_new_with_label ("Hide Fileops");
4466       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4467                           (GtkSignalFunc) file_selection_hide_fileops, 
4468                           (gpointer) window);
4469       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
4470                           button, FALSE, FALSE, 0);
4471       gtk_widget_show (button);
4472
4473       button = gtk_button_new_with_label ("Show Fileops");
4474       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4475                                  (GtkSignalFunc) gtk_file_selection_show_fileop_buttons, 
4476                                  (gpointer) window);
4477       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
4478                           button, FALSE, FALSE, 0);
4479       gtk_widget_show (button);
4480     }
4481   
4482   if (!GTK_WIDGET_VISIBLE (window))
4483     gtk_widget_show (window);
4484   else
4485     gtk_widget_destroy (window);
4486 }
4487
4488 /*
4489  * GtkFontSelection
4490  */
4491
4492 void
4493 font_selection_ok (GtkWidget              *w,
4494                    GtkFontSelectionDialog *fs)
4495 {
4496   g_print ("%s\n", gtk_font_selection_dialog_get_font_name (fs));
4497   gtk_widget_destroy (GTK_WIDGET (fs));
4498 }
4499
4500 void
4501 create_font_selection (void)
4502 {
4503   static GtkWidget *window = NULL;
4504
4505   if (!window)
4506     {
4507       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
4508
4509       gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
4510
4511       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4512                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4513                           &window);
4514
4515       gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
4516                           "clicked", GTK_SIGNAL_FUNC(font_selection_ok),
4517                           GTK_FONT_SELECTION_DIALOG (window));
4518       gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
4519                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
4520                                  GTK_OBJECT (window));
4521     }
4522   
4523   if (!GTK_WIDGET_VISIBLE (window))
4524     gtk_widget_show (window);
4525   else
4526     gtk_widget_destroy (window);
4527 }
4528
4529 /*
4530  * GtkDialog
4531  */
4532
4533 static GtkWidget *dialog_window = NULL;
4534
4535 void
4536 label_toggle (GtkWidget  *widget,
4537               GtkWidget **label)
4538 {
4539   if (!(*label))
4540     {
4541       *label = gtk_label_new ("Dialog Test");
4542       gtk_signal_connect (GTK_OBJECT (*label),
4543                           "destroy",
4544                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
4545                           label);
4546       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
4547       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
4548                           *label, TRUE, TRUE, 0);
4549       gtk_widget_show (*label);
4550     }
4551   else
4552     gtk_widget_destroy (*label);
4553 }
4554
4555 void
4556 create_dialog (void)
4557 {
4558   static GtkWidget *label;
4559   GtkWidget *button;
4560
4561   if (!dialog_window)
4562     {
4563       dialog_window = gtk_dialog_new ();
4564
4565       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
4566                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4567                           &dialog_window);
4568
4569       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
4570       gtk_container_border_width (GTK_CONTAINER (dialog_window), 0);
4571       gtk_widget_set_usize (dialog_window, 200, 110);
4572
4573       button = gtk_button_new_with_label ("OK");
4574       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4575       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
4576                           button, TRUE, TRUE, 0);
4577       gtk_widget_grab_default (button);
4578       gtk_widget_show (button);
4579
4580       button = gtk_button_new_with_label ("Toggle");
4581       gtk_signal_connect (GTK_OBJECT (button), "clicked",
4582                           GTK_SIGNAL_FUNC (label_toggle),
4583                           &label);
4584       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4585       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
4586                           button, TRUE, TRUE, 0);
4587       gtk_widget_show (button);
4588
4589       label = NULL;
4590     }
4591
4592   if (!GTK_WIDGET_VISIBLE (dialog_window))
4593     gtk_widget_show (dialog_window);
4594   else
4595     gtk_widget_destroy (dialog_window);
4596 }
4597
4598 /*
4599  * GtkRange
4600  */
4601
4602 void
4603 create_range_controls (void)
4604 {
4605   static GtkWidget *window = NULL;
4606   GtkWidget *box1;
4607   GtkWidget *box2;
4608   GtkWidget *button;
4609   GtkWidget *scrollbar;
4610   GtkWidget *scale;
4611   GtkWidget *separator;
4612   GtkObject *adjustment;
4613
4614   if (!window)
4615     {
4616       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4617
4618       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4619                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4620                           &window);
4621
4622       gtk_window_set_title (GTK_WINDOW (window), "range controls");
4623       gtk_container_border_width (GTK_CONTAINER (window), 0);
4624
4625
4626       box1 = gtk_vbox_new (FALSE, 0);
4627       gtk_container_add (GTK_CONTAINER (window), box1);
4628       gtk_widget_show (box1);
4629
4630
4631       box2 = gtk_vbox_new (FALSE, 10);
4632       gtk_container_border_width (GTK_CONTAINER (box2), 10);
4633       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4634       gtk_widget_show (box2);
4635
4636
4637       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
4638
4639       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
4640       gtk_widget_set_usize (GTK_WIDGET (scale), 150, 30);
4641       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
4642       gtk_scale_set_digits (GTK_SCALE (scale), 1);
4643       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
4644       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
4645       gtk_widget_show (scale);
4646
4647       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
4648       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
4649                                    GTK_UPDATE_CONTINUOUS);
4650       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
4651       gtk_widget_show (scrollbar);
4652
4653
4654       separator = gtk_hseparator_new ();
4655       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4656       gtk_widget_show (separator);
4657
4658
4659       box2 = gtk_vbox_new (FALSE, 10);
4660       gtk_container_border_width (GTK_CONTAINER (box2), 10);
4661       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4662       gtk_widget_show (box2);
4663
4664
4665       button = gtk_button_new_with_label ("close");
4666       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4667                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
4668                                  GTK_OBJECT (window));
4669       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4670       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4671       gtk_widget_grab_default (button);
4672       gtk_widget_show (button);
4673     }
4674
4675   if (!GTK_WIDGET_VISIBLE (window))
4676     gtk_widget_show (window);
4677   else
4678     gtk_widget_destroy (window);
4679 }
4680
4681 /*
4682  * GtkRulers
4683  */
4684
4685 void
4686 create_rulers (void)
4687 {
4688   static GtkWidget *window = NULL;
4689   GtkWidget *table;
4690   GtkWidget *ruler;
4691
4692   if (!window)
4693     {
4694       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4695       gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
4696
4697       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4698                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4699                           &window);
4700
4701       gtk_window_set_title (GTK_WINDOW (window), "rulers");
4702       gtk_widget_set_usize (window, 300, 300);
4703       gtk_widget_set_events (window, 
4704                              GDK_POINTER_MOTION_MASK 
4705                              | GDK_POINTER_MOTION_HINT_MASK);
4706       gtk_container_border_width (GTK_CONTAINER (window), 0);
4707
4708       table = gtk_table_new (2, 2, FALSE);
4709       gtk_container_add (GTK_CONTAINER (window), table);
4710       gtk_widget_show (table);
4711
4712       ruler = gtk_hruler_new ();
4713       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
4714       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
4715
4716       gtk_signal_connect_object (
4717         GTK_OBJECT (window), 
4718         "motion_notify_event",
4719         GTK_SIGNAL_FUNC(
4720           GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
4721         GTK_OBJECT (ruler));
4722
4723       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
4724                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
4725       gtk_widget_show (ruler);
4726
4727
4728       ruler = gtk_vruler_new ();
4729       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
4730
4731       gtk_signal_connect_object (
4732         GTK_OBJECT (window), 
4733         "motion_notify_event",
4734         GTK_SIGNAL_FUNC (GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event),
4735         GTK_OBJECT (ruler));
4736
4737       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
4738                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
4739       gtk_widget_show (ruler);
4740     }
4741
4742   if (!GTK_WIDGET_VISIBLE (window))
4743     gtk_widget_show (window);
4744   else
4745     gtk_widget_destroy (window);
4746 }
4747
4748 static void
4749 text_toggle_editable (GtkWidget *checkbutton,
4750                        GtkWidget *text)
4751 {
4752    gtk_text_set_editable(GTK_TEXT(text),
4753                           GTK_TOGGLE_BUTTON(checkbutton)->active);
4754 }
4755
4756 static void
4757 text_toggle_word_wrap (GtkWidget *checkbutton,
4758                        GtkWidget *text)
4759 {
4760    gtk_text_set_word_wrap(GTK_TEXT(text),
4761                           GTK_TOGGLE_BUTTON(checkbutton)->active);
4762 }
4763
4764 /*
4765  * GtkText
4766  */
4767
4768 void
4769 create_text (void)
4770 {
4771   static GtkWidget *window = NULL;
4772   GtkWidget *box1;
4773   GtkWidget *box2;
4774   GtkWidget *hbox;
4775   GtkWidget *button;
4776   GtkWidget *check;
4777   GtkWidget *separator;
4778   GtkWidget *table;
4779   GtkWidget *hscrollbar;
4780   GtkWidget *vscrollbar;
4781   GtkWidget *text;
4782
4783   FILE *infile;
4784
4785   if (!window)
4786     {
4787       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4788       gtk_widget_set_name (window, "text window");
4789       gtk_widget_set_usize (window, 500, 500);
4790       gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
4791
4792       gtk_signal_connect (GTK_OBJECT (window), "destroy",
4793                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
4794                           &window);
4795
4796       gtk_window_set_title (GTK_WINDOW (window), "test");
4797       gtk_container_border_width (GTK_CONTAINER (window), 0);
4798
4799
4800       box1 = gtk_vbox_new (FALSE, 0);
4801       gtk_container_add (GTK_CONTAINER (window), box1);
4802       gtk_widget_show (box1);
4803
4804
4805       box2 = gtk_vbox_new (FALSE, 10);
4806       gtk_container_border_width (GTK_CONTAINER (box2), 10);
4807       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
4808       gtk_widget_show (box2);
4809
4810
4811       table = gtk_table_new (2, 2, FALSE);
4812       gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
4813       gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
4814       gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
4815       gtk_widget_show (table);
4816
4817       text = gtk_text_new (NULL, NULL);
4818       gtk_text_set_editable (GTK_TEXT (text), TRUE);
4819       gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
4820                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
4821                         GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
4822       gtk_widget_show (text);
4823
4824       hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
4825       gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
4826                         GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL, 0, 0);
4827       gtk_widget_show (hscrollbar);
4828
4829       vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
4830       gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
4831                         GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
4832       gtk_widget_show (vscrollbar);
4833
4834       gtk_text_freeze (GTK_TEXT (text));
4835
4836       gtk_widget_realize (text);
4837
4838       infile = fopen("testgtk.c", "r");
4839       
4840       if (infile)
4841         {
4842           char buffer[1024];
4843           int nchars;
4844           
4845           while (1)
4846             {
4847               nchars = fread(buffer, 1, 1024, infile);
4848               gtk_text_insert (GTK_TEXT (text), NULL, NULL,
4849                                NULL, buffer, nchars);
4850               
4851               if (nchars < 1024)
4852                 break;
4853             }
4854           
4855           fclose (infile);
4856         }
4857       
4858       gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL, 
4859                        "And even ", -1);
4860       gtk_text_insert (GTK_TEXT (text), NULL, &text->style->bg[GTK_STATE_NORMAL], NULL, 
4861                        "colored", -1);
4862       gtk_text_insert (GTK_TEXT (text), NULL, &text->style->black, NULL, 
4863                        "text", -1);
4864
4865       gtk_text_thaw (GTK_TEXT (text));
4866
4867       hbox = gtk_hbutton_box_new ();
4868       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
4869       gtk_widget_show (hbox);
4870
4871       check = gtk_check_button_new_with_label("Editable");
4872       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
4873       gtk_signal_connect (GTK_OBJECT(check), "toggled",
4874                           GTK_SIGNAL_FUNC(text_toggle_editable), text);
4875       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), TRUE);
4876       gtk_widget_show (check);
4877
4878       check = gtk_check_button_new_with_label("Wrap Words");
4879       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
4880       gtk_signal_connect (GTK_OBJECT(check), "toggled",
4881                           GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
4882       gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), FALSE);
4883       gtk_widget_show (check);
4884
4885       separator = gtk_hseparator_new ();
4886       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4887       gtk_widget_show (separator);
4888
4889
4890       box2 = gtk_vbox_new (FALSE, 10);
4891       gtk_container_border_width (GTK_CONTAINER (box2), 10);
4892       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4893       gtk_widget_show (box2);
4894
4895
4896       button = gtk_button_new_with_label ("close");
4897       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
4898                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
4899                                  GTK_OBJECT (window));
4900       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4901       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
4902       gtk_widget_grab_default (button);
4903       gtk_widget_show (button);
4904     }
4905
4906   if (!GTK_WIDGET_VISIBLE (window))
4907     gtk_widget_show (window);
4908   else
4909     gtk_widget_destroy (window);
4910 }
4911
4912 /*
4913  * GtkNotebook
4914  */
4915
4916 GdkPixmap *book_open;
4917 GdkPixmap *book_closed;
4918 GdkBitmap *book_open_mask;
4919 GdkBitmap *book_closed_mask;
4920
4921 static void
4922 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
4923 {
4924   GtkNotebookPage *oldpage;
4925   GtkWidget *pixwid;
4926
4927   oldpage = GTK_NOTEBOOK (widget)->cur_page;
4928
4929   if (page == oldpage)
4930     return;
4931
4932   pixwid = ((GtkBoxChild*)(GTK_BOX (page->tab_label)->children->data))->widget;
4933   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
4934   pixwid = ((GtkBoxChild*) (GTK_BOX (page->menu_label)->children->data))->widget;
4935   gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask);
4936
4937   if (oldpage)
4938     {
4939       pixwid = ((GtkBoxChild*) (GTK_BOX 
4940                                 (oldpage->tab_label)->children->data))->widget;
4941       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
4942       pixwid = ((GtkBoxChild*) (GTK_BOX (oldpage->menu_label)->children->data))->widget;
4943       gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask);
4944     }
4945 }
4946
4947 static void
4948 create_pages (GtkNotebook *notebook, gint start, gint end)
4949 {
4950   GtkWidget *child = NULL;
4951   GtkWidget *label;
4952   GtkWidget *entry;
4953   GtkWidget *box;
4954   GtkWidget *hbox;
4955   GtkWidget *label_box;
4956   GtkWidget *menu_box;
4957   GtkWidget *button;
4958   GtkWidget *pixwid;
4959   gint i;
4960   char buffer[32];
4961
4962   for (i = start; i <= end; i++)
4963     {
4964       sprintf (buffer, "Page %d", i);
4965      
4966       switch (i % 4)
4967         {
4968         case 3:
4969           child = gtk_button_new_with_label (buffer);
4970           gtk_container_border_width (GTK_CONTAINER(child), 10);
4971           break;
4972         case 2:
4973           child = gtk_label_new (buffer);
4974           break;
4975         case 1:
4976           child = gtk_frame_new (buffer);
4977           gtk_container_border_width (GTK_CONTAINER (child), 10);
4978       
4979           box = gtk_vbox_new (TRUE,0);
4980           gtk_container_border_width (GTK_CONTAINER (box), 10);
4981           gtk_container_add (GTK_CONTAINER (child), box);
4982
4983           label = gtk_label_new (buffer);
4984           gtk_box_pack_start (GTK_BOX(box), label, TRUE, TRUE, 5);
4985
4986           entry = gtk_entry_new ();
4987           gtk_box_pack_start (GTK_BOX(box), entry, TRUE, TRUE, 5);
4988       
4989           hbox = gtk_hbox_new (TRUE,0);
4990           gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 5);
4991
4992           button = gtk_button_new_with_label ("Ok");
4993           gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5);
4994
4995           button = gtk_button_new_with_label ("Cancel");
4996           gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5);
4997           break;
4998         case 0:
4999           child = gtk_frame_new (buffer);
5000           gtk_container_border_width (GTK_CONTAINER (child), 10);
5001
5002           label = gtk_label_new (buffer);
5003           gtk_container_add (GTK_CONTAINER (child), label);
5004           break;
5005         }
5006
5007       gtk_widget_show_all (child);
5008
5009       label_box = gtk_hbox_new (FALSE, 0);
5010       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5011       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
5012       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5013       label = gtk_label_new (buffer);
5014       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
5015       gtk_widget_show_all (label_box);
5016       
5017       menu_box = gtk_hbox_new (FALSE, 0);
5018       pixwid = gtk_pixmap_new (book_closed, book_closed_mask);
5019       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
5020       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
5021       label = gtk_label_new (buffer);
5022       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
5023       gtk_widget_show_all (menu_box);
5024
5025       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
5026     }
5027 }
5028
5029 static void
5030 rotate_notebook (GtkButton   *button,
5031                  GtkNotebook *notebook)
5032 {
5033   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
5034 }
5035
5036 static void
5037 standard_notebook (GtkButton   *button,
5038                    GtkNotebook *notebook)
5039 {
5040   gint i;
5041
5042   gtk_notebook_set_show_tabs (notebook, TRUE);
5043   gtk_notebook_set_scrollable (notebook, FALSE);
5044   if (g_list_length (notebook->children) == 15)
5045     for (i = 0; i < 10; i++)
5046       gtk_notebook_remove_page (notebook, 5);
5047 }
5048
5049 static void
5050 notabs_notebook (GtkButton   *button,
5051                  GtkNotebook *notebook)
5052 {
5053   gint i;
5054
5055   gtk_notebook_set_show_tabs (notebook, FALSE);
5056   if (g_list_length (notebook->children) == 15)
5057     for (i = 0; i < 10; i++)
5058       gtk_notebook_remove_page (notebook, 5);
5059 }
5060
5061 static void
5062 scrollable_notebook (GtkButton   *button,
5063                      GtkNotebook *notebook)
5064 {
5065   gtk_notebook_set_show_tabs (notebook, TRUE);
5066   gtk_notebook_set_scrollable (notebook, TRUE);
5067   if (g_list_length (notebook->children) == 5)
5068     create_pages (notebook, 6, 15);
5069 }
5070
5071 static void
5072 notebook_popup (GtkToggleButton *button,
5073                 GtkNotebook     *notebook)
5074 {
5075   if (button->active)
5076     gtk_notebook_popup_enable (notebook);
5077   else
5078     gtk_notebook_popup_disable (notebook);
5079 }
5080
5081 static void
5082 create_notebook (void)
5083 {
5084   static GtkWidget *window = NULL;
5085   GtkWidget *box1;
5086   GtkWidget *box2;
5087   GtkWidget *button;
5088   GtkWidget *separator;
5089   GtkWidget *notebook;
5090   GtkWidget *omenu;
5091   GdkColor *transparent = NULL;
5092
5093   static OptionMenuItem items[] =
5094   {
5095     { "Standard",   standard_notebook },
5096     { "No tabs",    notabs_notebook },
5097     { "Scrollable", scrollable_notebook }
5098   };
5099
5100   if (!window)
5101     {
5102       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5103
5104       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5105                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5106                           &window);
5107
5108       gtk_window_set_title (GTK_WINDOW (window), "notebook");
5109       gtk_container_border_width (GTK_CONTAINER (window), 0);
5110
5111       box1 = gtk_vbox_new (FALSE, 0);
5112       gtk_container_add (GTK_CONTAINER (window), box1);
5113
5114       notebook = gtk_notebook_new ();
5115       gtk_signal_connect (GTK_OBJECT (notebook), "switch_page",
5116                           GTK_SIGNAL_FUNC (page_switch), NULL);
5117       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
5118       gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0);
5119       gtk_container_border_width (GTK_CONTAINER (notebook), 10);
5120
5121       gtk_widget_realize (notebook);
5122       book_open = gdk_pixmap_create_from_xpm_d (notebook->window,
5123                                                 &book_open_mask, 
5124                                                 transparent, 
5125                                                 book_open_xpm);
5126       book_closed = gdk_pixmap_create_from_xpm_d (notebook->window,
5127                                                   &book_closed_mask,
5128                                                   transparent, 
5129                                                   book_closed_xpm);
5130
5131       create_pages (GTK_NOTEBOOK (notebook), 1, 5);
5132
5133       separator = gtk_hseparator_new ();
5134       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
5135       
5136       box2 = gtk_hbox_new (TRUE, 5);
5137       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5138       
5139       omenu = build_option_menu (items, 3, 0, notebook);
5140       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, FALSE, 0);
5141
5142       button = gtk_check_button_new_with_label ("enable popup menu");
5143       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
5144       gtk_signal_connect (GTK_OBJECT(button), "clicked",
5145                           GTK_SIGNAL_FUNC (notebook_popup),
5146                           GTK_OBJECT (notebook));
5147       
5148       box2 = gtk_hbox_new (TRUE, 10);
5149       gtk_container_border_width (GTK_CONTAINER (box2), 10);
5150       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5151       
5152       button = gtk_button_new_with_label ("close");
5153       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5154                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
5155                                  GTK_OBJECT (window));
5156       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5157       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5158       gtk_widget_grab_default (button);
5159
5160       button = gtk_button_new_with_label ("next");
5161       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5162                                  GTK_SIGNAL_FUNC (gtk_notebook_next_page),
5163                                  GTK_OBJECT (notebook));
5164       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5165       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5166
5167       button = gtk_button_new_with_label ("prev");
5168       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5169                                  GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
5170                                  GTK_OBJECT (notebook));
5171       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5172       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5173
5174       button = gtk_button_new_with_label ("rotate");
5175       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5176                           GTK_SIGNAL_FUNC (rotate_notebook),
5177                           notebook);
5178       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5179       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5180     }
5181
5182   if (!GTK_WIDGET_VISIBLE (window))
5183     gtk_widget_show_all (window);
5184   else
5185     gtk_widget_destroy (window);
5186 }
5187
5188 /*
5189  * GtkPanes
5190  */
5191
5192 void
5193 create_panes (void)
5194 {
5195   static GtkWidget *window = NULL;
5196   GtkWidget *frame;
5197   GtkWidget *hpaned;
5198   GtkWidget *vpaned;
5199   GtkWidget *button;
5200
5201   if (!window)
5202     {
5203       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5204
5205       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5206                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5207                           &window);
5208
5209       gtk_window_set_title (GTK_WINDOW (window), "Panes");
5210       gtk_container_border_width (GTK_CONTAINER (window), 0);
5211
5212       vpaned = gtk_vpaned_new ();
5213       gtk_container_add (GTK_CONTAINER (window), vpaned);
5214       gtk_container_border_width (GTK_CONTAINER(vpaned), 5);
5215       gtk_widget_show (vpaned);
5216
5217       hpaned = gtk_hpaned_new ();
5218       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
5219
5220       frame = gtk_frame_new (NULL);
5221       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
5222       gtk_widget_set_usize (frame, 60, 60);
5223       gtk_paned_add1 (GTK_PANED (hpaned), frame);
5224       gtk_widget_show (frame);
5225       
5226       button = gtk_button_new_with_label ("Hi there");
5227       gtk_container_add (GTK_CONTAINER(frame), button);
5228       gtk_widget_show (button);
5229
5230       frame = gtk_frame_new (NULL);
5231       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
5232       gtk_widget_set_usize (frame, 80, 60);
5233       gtk_paned_add2 (GTK_PANED (hpaned), frame);
5234       gtk_widget_show (frame);
5235
5236       gtk_widget_show (hpaned);
5237
5238       frame = gtk_frame_new (NULL);
5239       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
5240       gtk_widget_set_usize (frame, 60, 80);
5241       gtk_paned_add2 (GTK_PANED (vpaned), frame);
5242       gtk_widget_show (frame);
5243     }
5244
5245   if (!GTK_WIDGET_VISIBLE (window))
5246     gtk_widget_show (window);
5247   else
5248     gtk_widget_destroy (window);
5249 }
5250
5251 /*
5252  * Drag -N- Drop
5253  */
5254
5255 gint
5256 dnd_drop_destroy_popup (GtkWidget *widget, GtkWindow **window)
5257 {
5258   if(GTK_IS_BUTTON(widget)) /* I.e. they clicked the close button */
5259     gtk_widget_destroy(GTK_WIDGET(*window));
5260   else {
5261     gtk_grab_remove(GTK_WIDGET(*window));
5262     *window = NULL;
5263   }
5264
5265   return FALSE;
5266 }
5267
5268 void
5269 dnd_drop (GtkWidget *button, GdkEvent *event)
5270 {
5271   static GtkWidget *window = NULL;
5272   GtkWidget *vbox, *lbl, *btn;
5273   gchar *msg;
5274
5275   /* DND doesn't obey gtk_grab's, so check if we're already displaying
5276    * drop modal dialog first
5277    */
5278   if (window)
5279     return;
5280
5281   window = gtk_window_new(GTK_WINDOW_DIALOG);
5282   gtk_container_border_width (GTK_CONTAINER(window), 10);
5283
5284   gtk_signal_connect (GTK_OBJECT (window), "destroy",
5285                       GTK_SIGNAL_FUNC(dnd_drop_destroy_popup),
5286                       &window);
5287   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
5288                       GTK_SIGNAL_FUNC(gtk_false),
5289                       &window);
5290
5291   vbox = gtk_vbox_new(FALSE, 5);
5292
5293   /* Display message that we got from drop source */
5294   msg = g_malloc(strlen(event->dropdataavailable.data)
5295                  + strlen(event->dropdataavailable.data_type) + 100);
5296   sprintf(msg, "Drop data of type %s was:\n\n%s",
5297           event->dropdataavailable.data_type,
5298           (char *)event->dropdataavailable.data);
5299   lbl = gtk_label_new(msg);
5300   gtk_label_set_justify(GTK_LABEL(lbl), GTK_JUSTIFY_FILL);
5301   g_free(msg);
5302   gtk_widget_show(lbl);
5303   gtk_box_pack_start_defaults(GTK_BOX(vbox), lbl);
5304
5305   /* Provide an obvious way out of this heinousness */
5306   btn = gtk_button_new_with_label("Continue with life in\nspite of this oppression");
5307   gtk_signal_connect_object (GTK_OBJECT (btn), "clicked",
5308                              GTK_SIGNAL_FUNC(gtk_widget_destroy),
5309                              GTK_OBJECT (window));
5310   gtk_widget_show(btn);
5311   gtk_box_pack_start_defaults(GTK_BOX(vbox), btn);
5312
5313   gtk_container_add(GTK_CONTAINER(window), vbox);
5314
5315   gtk_widget_show(vbox);
5316   gtk_grab_add(window);
5317   gtk_widget_show(window);
5318 }
5319
5320 void
5321 dnd_drag_request (GtkWidget *button, GdkEvent *event)
5322 {
5323 #define DND_STRING "Bill Gates demands royalties for\nyour use of his innovation."
5324   gtk_widget_dnd_data_set (button, event, DND_STRING, strlen(DND_STRING) + 1);
5325 }
5326
5327 void
5328 create_dnd (void)
5329 {
5330   static GtkWidget *window = NULL;
5331   GtkWidget *box1;
5332   GtkWidget *box2;
5333   GtkWidget *box3;
5334   GtkWidget *frame;
5335   GtkWidget *button;
5336   GtkWidget *separator;
5337
5338   /* For clarity... */
5339   char *possible_drag_types[] = {"text/plain"};
5340   char *accepted_drop_types[] = {"text/plain"};
5341
5342   static GtkWidget *drag_icon = NULL;
5343   static GtkWidget *drop_icon = NULL;
5344
5345   if (!window)
5346     {
5347       GdkPoint hotspot = {5,5};
5348       
5349       if (!drag_icon)
5350         {
5351           drag_icon = shape_create_icon ("Modeller.xpm",
5352                                          440, 140, 0,0, GTK_WINDOW_POPUP);
5353           
5354           gtk_signal_connect (GTK_OBJECT (drag_icon), "destroy",
5355                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5356                               &drag_icon);
5357
5358           gtk_widget_hide (drag_icon);
5359         }
5360       
5361       if (!drop_icon)
5362         {
5363           drop_icon = shape_create_icon ("3DRings.xpm",
5364                                          440, 140, 0,0, GTK_WINDOW_POPUP);
5365           
5366           gtk_signal_connect (GTK_OBJECT (drop_icon), "destroy",
5367                               GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5368                               &drop_icon);
5369
5370           gtk_widget_hide (drop_icon);
5371         }
5372
5373       gdk_dnd_set_drag_shape(drag_icon->window,
5374                              &hotspot,
5375                              drop_icon->window,
5376                              &hotspot);
5377
5378       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5379
5380       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5381                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5382                           &window);
5383
5384       gtk_window_set_title (GTK_WINDOW (window), "Drag -N- Drop");
5385       gtk_container_border_width (GTK_CONTAINER (window), 0);
5386
5387       box1 = gtk_vbox_new (FALSE, 0);
5388       gtk_container_add (GTK_CONTAINER (window), box1);
5389       gtk_widget_show (box1);
5390
5391       box2 = gtk_hbox_new (FALSE, 5);
5392       gtk_container_border_width (GTK_CONTAINER (box2), 10);
5393       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5394       gtk_widget_show (box2);
5395
5396       frame = gtk_frame_new ("Drag");
5397       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
5398       gtk_widget_show (frame);
5399
5400       box3 = gtk_vbox_new (FALSE, 5);
5401       gtk_container_border_width (GTK_CONTAINER (box3), 5);
5402       gtk_container_add (GTK_CONTAINER (frame), box3);
5403       gtk_widget_show (box3);
5404
5405       /*
5406        * FROM Button
5407        */
5408       button = gtk_button_new_with_label ("Drag me!");
5409       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
5410       gtk_widget_show (button);
5411
5412       /*
5413        * currently, the widget has to be realized to
5414        * set dnd on it, this needs to change
5415        */
5416       gtk_widget_realize (button);
5417       gtk_signal_connect (GTK_OBJECT (button),
5418                           "drag_request_event",
5419                           GTK_SIGNAL_FUNC(dnd_drag_request),
5420                           button);
5421       
5422       gtk_widget_dnd_drag_set (button, TRUE, possible_drag_types, 1);
5423
5424
5425       frame = gtk_frame_new ("Drop");
5426       gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
5427       gtk_widget_show (frame);
5428
5429       box3 = gtk_vbox_new (FALSE, 5);
5430       gtk_container_border_width (GTK_CONTAINER (box3), 5);
5431       gtk_container_add (GTK_CONTAINER (frame), box3);
5432       gtk_widget_show (box3);
5433
5434
5435       /*
5436        * TO Button
5437        */
5438       button = gtk_button_new_with_label ("To");
5439       gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
5440       gtk_widget_show (button);
5441
5442       gtk_widget_realize (button);
5443       gtk_signal_connect (GTK_OBJECT (button), 
5444                           "drop_data_available_event",
5445                           GTK_SIGNAL_FUNC(dnd_drop),
5446                           button);
5447
5448       gtk_widget_dnd_drop_set (button, TRUE, accepted_drop_types, 1, FALSE);
5449
5450
5451       separator = gtk_hseparator_new ();
5452       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5453       gtk_widget_show (separator);
5454
5455
5456       box2 = gtk_vbox_new (FALSE, 10);
5457       gtk_container_border_width (GTK_CONTAINER (box2), 10);
5458       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5459       gtk_widget_show (box2);
5460
5461
5462       button = gtk_button_new_with_label ("close");
5463
5464       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5465                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5466                                  GTK_OBJECT (window));
5467
5468       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5469       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5470       gtk_widget_grab_default (button);
5471       gtk_widget_show (button);
5472     }
5473
5474   if (!GTK_WIDGET_VISIBLE (window))
5475     gtk_widget_show (window);
5476   else
5477     gtk_widget_destroy (window);
5478 }
5479
5480 /*
5481  * Shaped Windows
5482  */
5483
5484 static GdkWindow *root_win = NULL;
5485
5486 typedef struct _cursoroffset {gint x,y;} CursorOffset;
5487
5488 static void
5489 shape_pressed (GtkWidget *widget, GdkEventButton *event)
5490 {
5491   CursorOffset *p;
5492
5493   /* ignore double and triple click */
5494   if (event->type != GDK_BUTTON_PRESS)
5495     return;
5496
5497   p = gtk_object_get_user_data (GTK_OBJECT(widget));
5498   p->x = (int) event->x;
5499   p->y = (int) event->y;
5500
5501   gtk_grab_add (widget);
5502   gdk_pointer_grab (widget->window, TRUE,
5503                     GDK_BUTTON_RELEASE_MASK |
5504                     GDK_BUTTON_MOTION_MASK |
5505                     GDK_POINTER_MOTION_HINT_MASK,
5506                     NULL, NULL, 0);
5507 }
5508
5509 static void
5510 shape_released (GtkWidget *widget)
5511 {
5512   gtk_grab_remove (widget);
5513   gdk_pointer_ungrab (0);
5514 }
5515
5516 static void
5517 shape_motion (GtkWidget      *widget, 
5518               GdkEventMotion *event)
5519 {
5520   gint xp, yp;
5521   CursorOffset * p;
5522   GdkModifierType mask;
5523
5524   p = gtk_object_get_user_data (GTK_OBJECT (widget));
5525
5526   /*
5527    * Can't use event->x / event->y here 
5528    * because I need absolute coordinates.
5529    */
5530   gdk_window_get_pointer (root_win, &xp, &yp, &mask);
5531   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
5532 }
5533
5534 GtkWidget *
5535 shape_create_icon (char     *xpm_file,
5536                    gint      x,
5537                    gint      y,
5538                    gint      px,
5539                    gint      py,
5540                    gint      window_type)
5541 {
5542   GtkWidget *window;
5543   GtkWidget *pixmap;
5544   GtkWidget *fixed;
5545   CursorOffset* icon_pos;
5546   GdkGC* gc;
5547   GdkBitmap *gdk_pixmap_mask;
5548   GdkPixmap *gdk_pixmap;
5549   GtkStyle *style;
5550
5551   style = gtk_widget_get_default_style ();
5552   gc = style->black_gc; 
5553
5554   /*
5555    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
5556    */
5557   window = gtk_window_new (window_type);
5558   
5559   fixed = gtk_fixed_new ();
5560   gtk_widget_set_usize (fixed, 100,100);
5561   gtk_container_add (GTK_CONTAINER (window), fixed);
5562   gtk_widget_show (fixed);
5563   
5564   gtk_widget_set_events (window, 
5565                          gtk_widget_get_events (window) |
5566                          GDK_BUTTON_MOTION_MASK |
5567                          GDK_POINTER_MOTION_HINT_MASK |
5568                          GDK_BUTTON_PRESS_MASK);
5569
5570   gtk_widget_realize (window);
5571   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
5572                                            &style->bg[GTK_STATE_NORMAL],
5573                                            xpm_file);
5574
5575   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
5576   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
5577   gtk_widget_show (pixmap);
5578   
5579   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px,py);
5580
5581
5582   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
5583                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
5584   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
5585                       GTK_SIGNAL_FUNC (shape_released),NULL);
5586   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
5587                       GTK_SIGNAL_FUNC (shape_motion),NULL);
5588
5589   icon_pos = g_new (CursorOffset, 1);
5590   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
5591
5592   gtk_widget_set_uposition (window, x, y);
5593   gtk_widget_show (window);
5594   
5595   return window;
5596 }
5597
5598 void 
5599 create_shapes (void)
5600 {
5601   /* Variables used by the Drag/Drop and Shape Window demos */
5602   static GtkWidget *modeller = NULL;
5603   static GtkWidget *sheets = NULL;
5604   static GtkWidget *rings = NULL;
5605
5606   root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
5607
5608   if (!modeller)
5609     {
5610       modeller = shape_create_icon ("Modeller.xpm",
5611                                     440, 140, 0,0, GTK_WINDOW_POPUP);
5612
5613       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
5614                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5615                           &modeller);
5616     }
5617   else
5618     gtk_widget_destroy (modeller);
5619
5620   if (!sheets)
5621     {
5622       sheets = shape_create_icon ("FilesQueue.xpm",
5623                                   580, 170, 0,0, GTK_WINDOW_POPUP);
5624
5625       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
5626                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5627                           &sheets);
5628
5629     }
5630   else
5631     gtk_widget_destroy (sheets);
5632
5633   if (!rings)
5634     {
5635       rings = shape_create_icon ("3DRings.xpm",
5636                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
5637
5638       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
5639                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5640                           &rings);
5641     }
5642   else
5643     gtk_widget_destroy (rings);
5644 }
5645
5646 /*
5647  * WM Hints demo
5648  */
5649
5650 void
5651 create_wmhints (void)
5652 {
5653   static GtkWidget *window = NULL;
5654   GtkWidget *label;
5655   GtkWidget *separator;
5656   GtkWidget *button;
5657   GtkWidget *box1;
5658   GtkWidget *box2;
5659
5660   GdkBitmap *circles;
5661
5662   if (!window)
5663     {
5664       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5665
5666       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5667                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5668                           &window);
5669
5670       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
5671       gtk_container_border_width (GTK_CONTAINER (window), 0);
5672
5673       gtk_widget_realize (window);
5674       
5675       circles = gdk_bitmap_create_from_data (window->window,
5676                                              circles_bits,
5677                                              circles_width,
5678                                              circles_height);
5679       gdk_window_set_icon (window->window, NULL,
5680                            circles, circles);
5681       
5682       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
5683   
5684       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
5685       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
5686       
5687       box1 = gtk_vbox_new (FALSE, 0);
5688       gtk_container_add (GTK_CONTAINER (window), box1);
5689       gtk_widget_show (box1);
5690
5691       label = gtk_label_new ("Try iconizing me!");
5692       gtk_widget_set_usize (label, 150, 50);
5693       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
5694       gtk_widget_show (label);
5695
5696
5697       separator = gtk_hseparator_new ();
5698       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5699       gtk_widget_show (separator);
5700
5701
5702       box2 = gtk_vbox_new (FALSE, 10);
5703       gtk_container_border_width (GTK_CONTAINER (box2), 10);
5704       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5705       gtk_widget_show (box2);
5706
5707
5708       button = gtk_button_new_with_label ("close");
5709
5710       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5711                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5712                                  GTK_OBJECT (window));
5713
5714       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5715       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5716       gtk_widget_grab_default (button);
5717       gtk_widget_show (button);
5718     }
5719
5720   if (!GTK_WIDGET_VISIBLE (window))
5721     gtk_widget_show (window);
5722   else
5723     gtk_widget_destroy (window);
5724 }
5725
5726 /*
5727  * GtkProgressBar
5728  */
5729
5730 typedef struct _ProgressData {
5731   GtkWidget *window;
5732   GtkWidget *pbar;
5733   GtkWidget *block_spin;
5734   GtkWidget *x_align_spin;
5735   GtkWidget *y_align_spin;
5736   GtkWidget *step_spin;
5737   GtkWidget *act_blocks_spin;
5738   GtkWidget *label;
5739   GtkWidget *omenu1;
5740   GtkWidget *omenu2;
5741   GtkWidget *entry;
5742   int timer;
5743 } ProgressData;
5744
5745 gint
5746 progress_timeout (gpointer data)
5747 {
5748   gfloat new_val;
5749   GtkAdjustment *adj;
5750
5751   adj = GTK_PROGRESS (data)->adjustment;
5752
5753   new_val = adj->value + 1;
5754   if (new_val > adj->upper)
5755     new_val = adj->lower;
5756
5757   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
5758
5759   return TRUE;
5760 }
5761
5762 static void
5763 destroy_progress (GtkWidget     *widget,
5764                   ProgressData **pdata)
5765 {
5766   gtk_timeout_remove ((*pdata)->timer);
5767   (*pdata)->timer = 0;
5768   (*pdata)->window = NULL;
5769   g_free (*pdata);
5770   *pdata = NULL;
5771 }
5772
5773 static void
5774 progressbar_toggle_orientation (GtkWidget *widget, ProgressData *pdata)
5775 {
5776   gint i;
5777
5778   if (!GTK_WIDGET_MAPPED (widget))
5779     return;
5780
5781   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
5782                     (((GtkOptionMenu *)(pdata->omenu1))->menu_item), i);
5783
5784   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
5785                             (GtkProgressBarOrientation) (3-i));
5786 }
5787
5788 static void
5789 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
5790 {
5791   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
5792                               GTK_TOGGLE_BUTTON (widget)->active);
5793   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
5794   gtk_widget_set_sensitive (pdata->x_align_spin,
5795                             GTK_TOGGLE_BUTTON (widget)->active);
5796   gtk_widget_set_sensitive (pdata->y_align_spin,
5797                             GTK_TOGGLE_BUTTON (widget)->active);
5798 }
5799
5800 static void
5801 progressbar_toggle_bar_style (GtkWidget *widget, ProgressData *pdata)
5802 {
5803   gint i;
5804
5805   if (!GTK_WIDGET_MAPPED (widget))
5806     return;
5807
5808   RADIOMENUTOGGLED ((GtkRadioMenuItem *)
5809                     (((GtkOptionMenu *)(pdata->omenu2))->menu_item), i);
5810
5811   i = 1 - i;
5812
5813   if (i == 1)
5814     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
5815   else
5816     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
5817
5818   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
5819                                   (GtkProgressBarStyle) i);
5820 }
5821
5822 static void
5823 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
5824 {
5825   char buf[20];
5826
5827   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
5828     sprintf (buf, "???");
5829   else
5830     sprintf (buf, "%.0f%%", 100 *
5831              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
5832   gtk_label_set (GTK_LABEL (pdata->label), buf);
5833 }
5834
5835 static void
5836 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
5837 {
5838   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
5839   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
5840      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
5841 }
5842
5843 static void
5844 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
5845 {
5846   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
5847      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
5848 }
5849
5850 static void
5851 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
5852 {
5853   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
5854                gtk_spin_button_get_value_as_int 
5855                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
5856 }
5857
5858 static void
5859 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
5860 {
5861   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
5862          gtk_spin_button_get_value_as_float 
5863                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
5864          gtk_spin_button_get_value_as_float
5865                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
5866 }
5867
5868 static void
5869 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
5870 {
5871   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
5872                                   GTK_TOGGLE_BUTTON (widget)->active);
5873   gtk_widget_set_sensitive (pdata->step_spin, 
5874                             GTK_TOGGLE_BUTTON (widget)->active);
5875   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
5876                             GTK_TOGGLE_BUTTON (widget)->active);
5877 }
5878
5879 static void
5880 entry_changed (GtkWidget *widget, ProgressData *pdata)
5881 {
5882   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
5883                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
5884 }
5885
5886 void
5887 create_progress_bar (void)
5888 {
5889   GtkWidget *button;
5890   GtkWidget *vbox;
5891   GtkWidget *vbox2;
5892   GtkWidget *hbox;
5893   GtkWidget *check;
5894   GtkWidget *frame;
5895   GtkWidget *tab;
5896   GtkWidget *label;
5897   GtkWidget *align;
5898   GtkAdjustment *adj;
5899   static ProgressData *pdata = NULL;
5900
5901   static OptionMenuItem items1[] =
5902   {
5903     { "Left-Right", progressbar_toggle_orientation },
5904     { "Right-Left", progressbar_toggle_orientation },
5905     { "Bottom-Top", progressbar_toggle_orientation },
5906     { "Top-Bottom", progressbar_toggle_orientation }
5907   };
5908
5909   static OptionMenuItem items2[] =
5910   {
5911     { "Continuous", progressbar_toggle_bar_style },
5912     { "Discrete",   progressbar_toggle_bar_style }
5913   };
5914
5915   if (!pdata)
5916     pdata = g_new0 (ProgressData, 1);
5917
5918   if (!pdata->window)
5919     {
5920       pdata->window = gtk_dialog_new ();
5921
5922       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
5923
5924       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
5925                           GTK_SIGNAL_FUNC (destroy_progress),
5926                           &pdata);
5927
5928       pdata->timer = 0;
5929
5930       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
5931       gtk_container_border_width (GTK_CONTAINER (pdata->window), 0);
5932
5933       vbox = gtk_vbox_new (FALSE, 5);
5934       gtk_container_border_width (GTK_CONTAINER (vbox), 10);
5935       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
5936                           vbox, FALSE, TRUE, 0);
5937
5938       frame = gtk_frame_new ("Progress");
5939       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
5940
5941       vbox2 = gtk_vbox_new (FALSE, 5);
5942       gtk_container_add (GTK_CONTAINER (frame), vbox2);
5943
5944       align = gtk_alignment_new (0.5, 0.5, 0, 0);
5945       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
5946
5947       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
5948       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
5949                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
5950
5951       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
5952       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
5953                                       "%v from [%l,%u] (=%p%%)");
5954       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
5955       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
5956
5957       align = gtk_alignment_new (0.5, 0.5, 0, 0);
5958       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
5959
5960       hbox = gtk_hbox_new (FALSE, 5);
5961       gtk_container_add (GTK_CONTAINER (align), hbox);
5962       label = gtk_label_new ("Label updated by user :"); 
5963       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5964       pdata->label = gtk_label_new ("");
5965       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
5966
5967       frame = gtk_frame_new ("Options");
5968       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
5969
5970       vbox2 = gtk_vbox_new (FALSE, 5);
5971       gtk_container_add (GTK_CONTAINER (frame), vbox2);
5972
5973       tab = gtk_table_new (7, 2, FALSE);
5974       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
5975
5976       label = gtk_label_new ("Orientation :");
5977       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
5978                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5979                         5, 5);
5980       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
5981
5982       pdata->omenu1 = build_option_menu (items1, 4, 0, pdata);
5983       hbox = gtk_hbox_new (FALSE, 0);
5984       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
5985                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5986                         5, 5);
5987       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
5988       
5989       check = gtk_check_button_new_with_label ("Show text");
5990       gtk_signal_connect (GTK_OBJECT (check), "clicked",
5991                           GTK_SIGNAL_FUNC (toggle_show_text),
5992                           pdata);
5993       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
5994                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5995                         5, 5);
5996
5997       hbox = gtk_hbox_new (FALSE, 0);
5998       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
5999                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6000                         5, 5);
6001
6002       label = gtk_label_new ("Format : ");
6003       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6004
6005       pdata->entry = gtk_entry_new ();
6006       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
6007                           GTK_SIGNAL_FUNC (entry_changed),
6008                           pdata);
6009       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
6010       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
6011       gtk_widget_set_usize (pdata->entry, 100, -1);
6012       gtk_widget_set_sensitive (pdata->entry, FALSE);
6013
6014       label = gtk_label_new ("Text align :");
6015       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
6016                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6017                         5, 5);
6018       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
6019
6020       hbox = gtk_hbox_new (FALSE, 0);
6021       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
6022                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6023                         5, 5);
6024
6025       label = gtk_label_new ("x :");
6026       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
6027       
6028       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
6029       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
6030       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6031                           GTK_SIGNAL_FUNC (adjust_align), pdata);
6032       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
6033       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
6034
6035       label = gtk_label_new ("y :");
6036       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
6037
6038       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
6039       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
6040       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6041                           GTK_SIGNAL_FUNC (adjust_align), pdata);
6042       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
6043       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
6044
6045       label = gtk_label_new ("Bar Style :");
6046       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
6047                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6048                         5, 5);
6049       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
6050
6051       pdata->omenu2 = build_option_menu (items2, 2, 0, pdata);
6052       hbox = gtk_hbox_new (FALSE, 0);
6053       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
6054                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6055                         5, 5);
6056       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
6057
6058       label = gtk_label_new ("Block count :");
6059       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
6060                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6061                         5, 5);
6062       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
6063
6064       hbox = gtk_hbox_new (FALSE, 0);
6065       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
6066                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6067                         5, 5);
6068       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
6069       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
6070       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6071                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
6072       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
6073       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
6074
6075       check = gtk_check_button_new_with_label ("Activity mode");
6076       gtk_signal_connect (GTK_OBJECT (check), "clicked",
6077                           GTK_SIGNAL_FUNC (toggle_activity_mode),
6078                           pdata);
6079       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
6080                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6081                         5, 5);
6082
6083       hbox = gtk_hbox_new (FALSE, 0);
6084       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
6085                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6086                         5, 5);
6087       label = gtk_label_new ("Step size : ");
6088       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6089       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
6090       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
6091       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6092                           GTK_SIGNAL_FUNC (adjust_step), pdata);
6093       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
6094       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
6095
6096       hbox = gtk_hbox_new (FALSE, 0);
6097       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
6098                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
6099                         5, 5);
6100       label = gtk_label_new ("Blocks :     ");
6101       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6102       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
6103       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
6104       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6105                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
6106       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
6107                           0);
6108       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
6109
6110       button = gtk_button_new_with_label ("close");
6111       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6112                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
6113                                  GTK_OBJECT (pdata->window));
6114       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6115       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
6116                           button, TRUE, TRUE, 0);
6117       gtk_widget_grab_default (button);
6118     }
6119
6120   if (!GTK_WIDGET_VISIBLE (pdata->window))
6121     gtk_widget_show_all (pdata->window);
6122   else
6123     gtk_widget_destroy (pdata->window);
6124 }
6125
6126 /*
6127  * Color Preview
6128  */
6129
6130 static int color_idle = 0;
6131
6132 gint
6133 color_idle_func (GtkWidget *preview)
6134 {
6135   static int count = 1;
6136   guchar buf[768];
6137   int i, j, k;
6138
6139   for (i = 0; i < 256; i++)
6140     {
6141       for (j = 0, k = 0; j < 256; j++)
6142         {
6143           buf[k+0] = i + count;
6144           buf[k+1] = 0;
6145           buf[k+2] = j + count;
6146           k += 3;
6147         }
6148
6149       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
6150     }
6151
6152   count += 1;
6153
6154   gtk_widget_draw (preview, NULL);
6155
6156   return TRUE;
6157 }
6158
6159 static void
6160 color_preview_destroy (GtkWidget  *widget,
6161                        GtkWidget **window)
6162 {
6163   gtk_idle_remove (color_idle);
6164   color_idle = 0;
6165
6166   *window = NULL;
6167 }
6168
6169 void
6170 create_color_preview (void)
6171 {
6172   static GtkWidget *window = NULL;
6173   GtkWidget *preview;
6174   guchar buf[768];
6175   int i, j, k;
6176
6177   if (!window)
6178     {
6179       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6180
6181       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6182                           GTK_SIGNAL_FUNC(color_preview_destroy),
6183                           &window);
6184
6185       gtk_window_set_title (GTK_WINDOW (window), "test");
6186       gtk_container_border_width (GTK_CONTAINER (window), 10);
6187
6188       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
6189       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
6190       gtk_container_add (GTK_CONTAINER (window), preview);
6191
6192       for (i = 0; i < 256; i++)
6193         {
6194           for (j = 0, k = 0; j < 256; j++)
6195             {
6196               buf[k+0] = i;
6197               buf[k+1] = 0;
6198               buf[k+2] = j;
6199               k += 3;
6200             }
6201
6202           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
6203         }
6204
6205       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
6206     }
6207
6208   if (!GTK_WIDGET_VISIBLE (window))
6209     gtk_widget_show_all (window);
6210   else
6211     gtk_widget_destroy (window);
6212 }
6213
6214 /*
6215  * Gray Preview
6216  */
6217
6218 static int gray_idle = 0;
6219
6220 gint
6221 gray_idle_func (GtkWidget *preview)
6222 {
6223   static int count = 1;
6224   guchar buf[256];
6225   int i, j;
6226
6227   for (i = 0; i < 256; i++)
6228     {
6229       for (j = 0; j < 256; j++)
6230         buf[j] = i + j + count;
6231
6232       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
6233     }
6234
6235   count += 1;
6236
6237   gtk_widget_draw (preview, NULL);
6238
6239   return TRUE;
6240 }
6241
6242 static void
6243 gray_preview_destroy (GtkWidget  *widget,
6244                       GtkWidget **window)
6245 {
6246   gtk_idle_remove (gray_idle);
6247   gray_idle = 0;
6248
6249   *window = NULL;
6250 }
6251
6252 void
6253 create_gray_preview (void)
6254 {
6255   static GtkWidget *window = NULL;
6256   GtkWidget *preview;
6257   guchar buf[256];
6258   int i, j;
6259
6260   if (!window)
6261     {
6262       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6263
6264       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6265                           GTK_SIGNAL_FUNC(gray_preview_destroy),
6266                           &window);
6267
6268       gtk_window_set_title (GTK_WINDOW (window), "test");
6269       gtk_container_border_width (GTK_CONTAINER (window), 10);
6270
6271       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
6272       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
6273       gtk_container_add (GTK_CONTAINER (window), preview);
6274
6275       for (i = 0; i < 256; i++)
6276         {
6277           for (j = 0; j < 256; j++)
6278             buf[j] = i + j;
6279
6280           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
6281         }
6282
6283       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
6284     }
6285
6286   if (!GTK_WIDGET_VISIBLE (window))
6287     gtk_widget_show_all (window);
6288   else
6289     gtk_widget_destroy (window);
6290 }
6291
6292
6293 /*
6294  * Selection Test
6295  */
6296
6297 void
6298 selection_test_received (GtkWidget *list, GtkSelectionData *data)
6299 {
6300   GdkAtom *atoms;
6301   GtkWidget *list_item;
6302   GList *item_list;
6303   int i, l;
6304
6305   if (data->length < 0)
6306     {
6307       g_print ("Selection retrieval failed\n");
6308       return;
6309     }
6310   if (data->type != GDK_SELECTION_TYPE_ATOM)
6311     {
6312       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
6313       return;
6314     }
6315
6316   /* Clear out any current list items */
6317
6318   gtk_list_clear_items (GTK_LIST(list), 0, -1);
6319
6320   /* Add new items to list */
6321
6322   atoms = (GdkAtom *)data->data;
6323
6324   item_list = NULL;
6325   l = data->length / sizeof (GdkAtom);
6326   for (i = 0; i < l; i++)
6327     {
6328       char *name;
6329       name = gdk_atom_name (atoms[i]);
6330       if (name != NULL)
6331         {
6332           list_item = gtk_list_item_new_with_label (name);
6333           g_free (name);
6334         }
6335       else
6336         list_item = gtk_list_item_new_with_label ("(bad atom)");
6337
6338       gtk_widget_show (list_item);
6339       item_list = g_list_append (item_list, list_item);
6340     }
6341
6342   gtk_list_append_items (GTK_LIST (list), item_list);
6343
6344   return;
6345 }
6346
6347 void
6348 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
6349 {
6350   static GdkAtom targets_atom = GDK_NONE;
6351
6352   if (targets_atom == GDK_NONE)
6353     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
6354
6355   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
6356                          GDK_CURRENT_TIME);
6357 }
6358
6359 void
6360 create_selection_test (void)
6361 {
6362   static GtkWidget *window = NULL;
6363   GtkWidget *button;
6364   GtkWidget *vbox;
6365   GtkWidget *scrolled_win;
6366   GtkWidget *list;
6367   GtkWidget *label;
6368
6369   if (!window)
6370     {
6371       window = gtk_dialog_new ();
6372
6373       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6374                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6375                           &window);
6376
6377       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
6378       gtk_container_border_width (GTK_CONTAINER (window), 0);
6379
6380       /* Create the list */
6381
6382       vbox = gtk_vbox_new (FALSE, 5);
6383       gtk_container_border_width (GTK_CONTAINER (vbox), 10);
6384       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
6385                           TRUE, TRUE, 0);
6386
6387       label = gtk_label_new ("Gets available targets for current selection");
6388       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
6389
6390       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6391       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6392                                       GTK_POLICY_AUTOMATIC, 
6393                                       GTK_POLICY_AUTOMATIC);
6394       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6395       gtk_widget_set_usize (scrolled_win, 100, 200);
6396
6397       list = gtk_list_new ();
6398       gtk_container_add (GTK_CONTAINER (scrolled_win), list);
6399
6400       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
6401                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
6402
6403       /* .. And create some buttons */
6404       button = gtk_button_new_with_label ("Get Targets");
6405       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
6406                           button, TRUE, TRUE, 0);
6407
6408       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6409                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
6410
6411       button = gtk_button_new_with_label ("Quit");
6412       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
6413                           button, TRUE, TRUE, 0);
6414
6415       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6416                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
6417                                  GTK_OBJECT (window));
6418     }
6419
6420   if (!GTK_WIDGET_VISIBLE (window))
6421     gtk_widget_show_all (window);
6422   else
6423     gtk_widget_destroy (window);
6424 }
6425
6426 /*
6427  * Gamma Curve
6428  */
6429
6430 void
6431 create_gamma_curve (void)
6432 {
6433   static GtkWidget *window = NULL, *curve;
6434   static int count = 0;
6435   gfloat vec[256];
6436   gint max;
6437   gint i;
6438
6439   if (!window)
6440     {
6441       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6442       gtk_window_set_title (GTK_WINDOW (window), "test");
6443       gtk_container_border_width (GTK_CONTAINER (window), 10);
6444
6445       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6446                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6447                           &window);
6448
6449       curve = gtk_gamma_curve_new ();
6450       gtk_container_add (GTK_CONTAINER (window), curve);
6451       gtk_widget_show (curve);
6452     }
6453
6454   max = 127 + (count % 2)*128;
6455   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
6456                        0, max, 0, max);
6457   for (i = 0; i < max; ++i)
6458     vec[i] = (127 / sqrt (max)) * sqrt (i);
6459   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
6460                         max, vec);
6461
6462   if (!GTK_WIDGET_VISIBLE (window))
6463     gtk_widget_show (window);
6464   else if (count % 4 == 3)
6465     {
6466       gtk_widget_destroy (window);
6467       window = NULL;
6468     }
6469
6470   ++count;
6471 }
6472
6473 /*
6474  * Test scrolling
6475  */
6476
6477 static int scroll_test_pos = 0.0;
6478 static GdkGC *scroll_test_gc = NULL;
6479
6480 static gint
6481 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
6482                     GtkAdjustment *adj)
6483 {
6484   gint i,j;
6485   gint imin, imax, jmin, jmax;
6486   
6487   imin = (event->area.x) / 10;
6488   imax = (event->area.x + event->area.width + 9) / 10;
6489
6490   jmin = ((int)adj->value + event->area.y) / 10;
6491   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
6492
6493   gdk_window_clear_area (widget->window,
6494                          event->area.x, event->area.y,
6495                          event->area.width, event->area.height);
6496
6497   for (i=imin; i<imax; i++)
6498     for (j=jmin; j<jmax; j++)
6499       if ((i+j) % 2)
6500         gdk_draw_rectangle (widget->window, 
6501                             widget->style->black_gc,
6502                             TRUE,
6503                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
6504
6505   return TRUE;
6506 }
6507
6508 static void
6509 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
6510                        GtkAdjustment *adj)
6511 {
6512   adj->page_increment = 0.9 * widget->allocation.height;
6513   adj->page_size = widget->allocation.height;
6514
6515   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
6516 }
6517
6518 static void
6519 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
6520 {
6521   gint source_min = (int)adj->value - scroll_test_pos;
6522   gint source_max = source_min + widget->allocation.height;
6523   gint dest_min = 0;
6524   gint dest_max = widget->allocation.height;
6525   GdkRectangle rect;
6526   GdkEvent *event;
6527
6528   scroll_test_pos = adj->value;
6529
6530   if (!GTK_WIDGET_DRAWABLE (widget))
6531     return;
6532
6533   if (source_min < 0)
6534     {
6535       rect.x = 0; 
6536       rect.y = 0;
6537       rect.width = widget->allocation.width;
6538       rect.height = -source_min;
6539       if (rect.height > widget->allocation.height)
6540         rect.height = widget->allocation.height;
6541
6542       source_min = 0;
6543       dest_min = rect.height;
6544     }
6545   else
6546     {
6547       rect.x = 0;
6548       rect.y = 2*widget->allocation.height - source_max;
6549       if (rect.y < 0)
6550         rect.y = 0;
6551       rect.width = widget->allocation.width;
6552       rect.height = widget->allocation.height - rect.y;
6553
6554       source_max = widget->allocation.height;
6555       dest_max = rect.y;
6556     }
6557
6558   if (source_min != source_max)
6559     {
6560       if (scroll_test_gc == NULL)
6561         {
6562           scroll_test_gc = gdk_gc_new (widget->window);
6563           gdk_gc_set_exposures (scroll_test_gc, TRUE);
6564         }
6565
6566       gdk_draw_pixmap (widget->window,
6567                        scroll_test_gc,
6568                        widget->window,
6569                        0, source_min,
6570                        0, dest_min,
6571                        widget->allocation.width,
6572                        source_max - source_min);
6573
6574       /* Make sure graphics expose events are processed before scrolling
6575        * again */
6576       
6577       while ((event = gdk_event_get_graphics_expose (widget->window)) != NULL)
6578         {
6579           gtk_widget_event (widget, event);
6580           if (event->expose.count == 0)
6581             {
6582               gdk_event_free (event);
6583               break;
6584             }
6585           gdk_event_free (event);
6586         }
6587     }
6588
6589   if (rect.height != 0)
6590     gtk_widget_draw (widget, &rect);
6591 }
6592
6593
6594 void
6595 create_scroll_test (void)
6596 {
6597   static GtkWidget *window = NULL;
6598   GtkWidget *hbox;
6599   GtkWidget *drawing_area;
6600   GtkWidget *scrollbar;
6601   GtkWidget *button;
6602   GtkAdjustment *adj;
6603   
6604   if (!window)
6605     {
6606       window = gtk_dialog_new ();
6607
6608       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6609                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6610                           &window);
6611
6612       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
6613       gtk_container_border_width (GTK_CONTAINER (window), 0);
6614
6615       hbox = gtk_hbox_new (FALSE, 0);
6616       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
6617                           TRUE, TRUE, 0);
6618       gtk_widget_show (hbox);
6619
6620       drawing_area = gtk_drawing_area_new ();
6621       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
6622       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
6623       gtk_widget_show (drawing_area);
6624
6625       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK);
6626
6627       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
6628       scroll_test_pos = 0.0;
6629
6630       scrollbar = gtk_vscrollbar_new (adj);
6631       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
6632       gtk_widget_show (scrollbar);
6633
6634       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
6635                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
6636       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
6637                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
6638
6639       
6640       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6641                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
6642                           drawing_area);
6643       
6644       /* .. And create some buttons */
6645
6646       button = gtk_button_new_with_label ("Quit");
6647       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
6648                           button, TRUE, TRUE, 0);
6649
6650       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6651                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
6652                                  GTK_OBJECT (window));
6653       gtk_widget_show (button);
6654     }
6655
6656   if (!GTK_WIDGET_VISIBLE (window))
6657     gtk_widget_show (window);
6658   else
6659     gtk_widget_destroy (window);
6660 }
6661
6662 /*
6663  * Timeout Test
6664  */
6665
6666 static int timer = 0;
6667
6668 gint
6669 timeout_test (GtkWidget *label)
6670 {
6671   static int count = 0;
6672   static char buffer[32];
6673
6674   sprintf (buffer, "count: %d", ++count);
6675   gtk_label_set (GTK_LABEL (label), buffer);
6676
6677   return TRUE;
6678 }
6679
6680 void
6681 start_timeout_test (GtkWidget *widget,
6682                     GtkWidget *label)
6683 {
6684   if (!timer)
6685     {
6686       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
6687     }
6688 }
6689
6690 void
6691 stop_timeout_test (GtkWidget *widget,
6692                    gpointer   data)
6693 {
6694   if (timer)
6695     {
6696       gtk_timeout_remove (timer);
6697       timer = 0;
6698     }
6699 }
6700
6701 void
6702 destroy_timeout_test (GtkWidget  *widget,
6703                       GtkWidget **window)
6704 {
6705   stop_timeout_test (NULL, NULL);
6706
6707   *window = NULL;
6708 }
6709
6710 void
6711 create_timeout_test (void)
6712 {
6713   static GtkWidget *window = NULL;
6714   GtkWidget *button;
6715   GtkWidget *label;
6716
6717   if (!window)
6718     {
6719       window = gtk_dialog_new ();
6720
6721       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6722                           GTK_SIGNAL_FUNC(destroy_timeout_test),
6723                           &window);
6724
6725       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
6726       gtk_container_border_width (GTK_CONTAINER (window), 0);
6727
6728       label = gtk_label_new ("count: 0");
6729       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
6730       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
6731                           label, TRUE, TRUE, 0);
6732       gtk_widget_show (label);
6733
6734       button = gtk_button_new_with_label ("close");
6735       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6736                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6737                                  GTK_OBJECT (window));
6738       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6739       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6740                           button, TRUE, TRUE, 0);
6741       gtk_widget_grab_default (button);
6742       gtk_widget_show (button);
6743
6744       button = gtk_button_new_with_label ("start");
6745       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6746                           GTK_SIGNAL_FUNC(start_timeout_test),
6747                           label);
6748       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6749       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6750                           button, TRUE, TRUE, 0);
6751       gtk_widget_show (button);
6752
6753       button = gtk_button_new_with_label ("stop");
6754       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6755                           GTK_SIGNAL_FUNC(stop_timeout_test),
6756                           NULL);
6757       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6758       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6759                           button, TRUE, TRUE, 0);
6760       gtk_widget_show (button);
6761     }
6762
6763   if (!GTK_WIDGET_VISIBLE (window))
6764     gtk_widget_show (window);
6765   else
6766     gtk_widget_destroy (window);
6767 }
6768
6769 /*
6770  * Idle Test
6771  */
6772
6773 static int idle = 0;
6774
6775 static gint
6776 idle_test (GtkWidget *label)
6777 {
6778   static int count = 0;
6779   static char buffer[32];
6780
6781   sprintf (buffer, "count: %d", ++count);
6782   gtk_label_set (GTK_LABEL (label), buffer);
6783
6784   return TRUE;
6785 }
6786
6787 static void
6788 start_idle_test (GtkWidget *widget,
6789                  GtkWidget *label)
6790 {
6791   if (!idle)
6792     {
6793       idle = gtk_idle_add ((GtkFunction) idle_test, label);
6794     }
6795 }
6796
6797 static void
6798 stop_idle_test (GtkWidget *widget,
6799                 gpointer   data)
6800 {
6801   if (idle)
6802     {
6803       gtk_idle_remove (idle);
6804       idle = 0;
6805     }
6806 }
6807
6808 static void
6809 destroy_idle_test (GtkWidget  *widget,
6810                    GtkWidget **window)
6811 {
6812   stop_idle_test (NULL, NULL);
6813
6814   *window = NULL;
6815 }
6816
6817 static void
6818 toggle_idle_container (GtkObject *button,
6819                        GtkContainer *container)
6820 {
6821   gtk_container_set_resize_mode (container, (guint) gtk_object_get_user_data (button));
6822 }
6823
6824 static void
6825 create_idle_test (void)
6826 {
6827   static GtkWidget *window = NULL;
6828   GtkWidget *button;
6829   GtkWidget *label;
6830   GtkWidget *container;
6831
6832   if (!window)
6833     {
6834       GtkWidget *frame;
6835       GtkWidget *box;
6836
6837       window = gtk_dialog_new ();
6838
6839       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6840                           GTK_SIGNAL_FUNC(destroy_idle_test),
6841                           &window);
6842
6843       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
6844       gtk_container_border_width (GTK_CONTAINER (window), 0);
6845
6846       label = gtk_label_new ("count: 0");
6847       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
6848       gtk_widget_show (label);
6849       
6850       container =
6851         gtk_widget_new (GTK_TYPE_HBOX,
6852                         "GtkWidget::visible", TRUE,
6853                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
6854                          * "GtkWidget::visible", TRUE,
6855                          */
6856                          "GtkContainer::child", label,
6857                         /* NULL), */
6858                         NULL);
6859       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
6860                           container, TRUE, TRUE, 0);
6861
6862       frame =
6863         gtk_widget_new (GTK_TYPE_FRAME,
6864                         "GtkContainer::border_width", 5,
6865                         "GtkFrame::label", "Label Container",
6866                         "GtkWidget::visible", TRUE,
6867                         "GtkWidget::parent", GTK_DIALOG (window)->vbox,
6868                         NULL);
6869       box =
6870         gtk_widget_new (GTK_TYPE_VBOX,
6871                         "GtkWidget::visible", TRUE,
6872                         "GtkWidget::parent", frame,
6873                         NULL);
6874       button =
6875         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
6876                         "GtkButton::label", "Resize-Parent",
6877                         "GtkObject::user_data", (void*)GTK_RESIZE_PARENT,
6878                         "GtkObject::signal::clicked", toggle_idle_container, container,
6879                         "GtkWidget::visible", TRUE,
6880                         "GtkWidget::parent", box,
6881                         NULL);
6882       button =
6883         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
6884                         "GtkButton::label", "Resize-Queue",
6885                         "GtkObject::user_data", (void*)GTK_RESIZE_QUEUE,
6886                         "GtkObject::signal::clicked", toggle_idle_container, container,
6887                         "GtkRadioButton::group", button,
6888                         "GtkWidget::visible", TRUE,
6889                         "GtkWidget::parent", box,
6890                         NULL);
6891       button =
6892         gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
6893                         "GtkButton::label", "Resize-Immediate",
6894                         "GtkObject::user_data", (void*)GTK_RESIZE_IMMEDIATE,
6895                         "GtkObject::signal::clicked", toggle_idle_container, container,
6896                         "GtkRadioButton::group", button,
6897                         "GtkWidget::visible", TRUE,
6898                         "GtkWidget::parent", box,
6899                         NULL);
6900       
6901
6902       button = gtk_button_new_with_label ("close");
6903       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6904                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
6905                                  GTK_OBJECT (window));
6906       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6907       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6908                           button, TRUE, TRUE, 0);
6909       gtk_widget_grab_default (button);
6910       gtk_widget_show (button);
6911
6912       button = gtk_button_new_with_label ("start");
6913       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6914                           GTK_SIGNAL_FUNC(start_idle_test),
6915                           label);
6916       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6917       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6918                           button, TRUE, TRUE, 0);
6919       gtk_widget_show (button);
6920
6921       button = gtk_button_new_with_label ("stop");
6922       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6923                           GTK_SIGNAL_FUNC(stop_idle_test),
6924                           NULL);
6925       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
6926       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6927                           button, TRUE, TRUE, 0);
6928       gtk_widget_show (button);
6929     }
6930
6931   if (!GTK_WIDGET_VISIBLE (window))
6932     gtk_widget_show (window);
6933   else
6934     gtk_widget_destroy (window);
6935 }
6936
6937 /*
6938  * rc file test
6939  */
6940
6941 void
6942 reload_rc_file (void)
6943 {
6944   GList *toplevels;
6945
6946   if (gtk_rc_reparse_all ())
6947     {
6948       toplevels = gdk_window_get_toplevels();
6949       while (toplevels)
6950         {
6951           GtkWidget *widget;
6952           gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
6953           
6954           if (widget)
6955             gtk_widget_reset_rc_styles (widget);
6956           
6957           toplevels = toplevels->next;
6958         }
6959       g_list_free (toplevels);
6960     }
6961 }
6962
6963 void
6964 reload_all_rc_files (void)
6965 {
6966   static GdkAtom atom_rcfiles = GDK_NONE;
6967
6968   GdkEventClient sev;
6969   int i;
6970   
6971   if (!atom_rcfiles)
6972     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
6973
6974   for(i = 0; i < 5; i++)
6975     sev.data.l[i] = 0;
6976   sev.data_format = 32;
6977   sev.message_type = atom_rcfiles;
6978   gdk_event_send_clientmessage_toall ((GdkEvent *) &sev);
6979 }
6980
6981 void
6982 create_rc_file (void)
6983 {
6984   static GtkWidget *window = NULL;
6985   GtkWidget *button;
6986
6987   if (!window)
6988     {
6989       window = gtk_dialog_new ();
6990
6991       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6992                           GTK_SIGNAL_FUNC(destroy_idle_test),
6993                           &window);
6994
6995       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
6996       gtk_container_border_width (GTK_CONTAINER (window), 0);
6997
6998       button = gtk_button_new_with_label ("Reload");
6999       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7000                           GTK_SIGNAL_FUNC(reload_rc_file), NULL);
7001       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7002       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7003                           button, TRUE, TRUE, 0);
7004       gtk_widget_grab_default (button);
7005       gtk_widget_show (button);
7006
7007       button = gtk_button_new_with_label ("Reload All");
7008       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7009                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
7010       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7011       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7012                           button, TRUE, TRUE, 0);
7013       gtk_widget_show (button);
7014
7015       button = gtk_button_new_with_label ("Close");
7016       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7017                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7018                                  GTK_OBJECT (window));
7019       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7020       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
7021                           button, TRUE, TRUE, 0);
7022       gtk_widget_show (button);
7023
7024     }
7025
7026   if (!GTK_WIDGET_VISIBLE (window))
7027     gtk_widget_show (window);
7028   else
7029     gtk_widget_destroy (window);
7030 }
7031
7032 /*
7033  * Test of recursive mainloop
7034  */
7035
7036 void
7037 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
7038 {
7039   *window = NULL;
7040   gtk_main_quit ();
7041 }
7042
7043 void
7044 create_mainloop (void)
7045 {
7046   static GtkWidget *window = NULL;
7047   GtkWidget *label;
7048   GtkWidget *button;
7049
7050   if (!window)
7051     {
7052       window = gtk_dialog_new ();
7053
7054       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
7055
7056       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7057                           GTK_SIGNAL_FUNC(mainloop_destroyed),
7058                           &window);
7059
7060       label = gtk_label_new ("In recursive main loop...");
7061       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
7062
7063       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
7064                           TRUE, TRUE, 0);
7065       gtk_widget_show (label);
7066
7067       button = gtk_button_new_with_label ("Leave");
7068       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
7069                           FALSE, TRUE, 0);
7070
7071       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7072                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7073                                  GTK_OBJECT (window));
7074
7075       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7076       gtk_widget_grab_default (button);
7077
7078       gtk_widget_show (button);
7079     }
7080
7081   if (!GTK_WIDGET_VISIBLE (window))
7082     {
7083       gtk_widget_show (window);
7084
7085       g_print ("create_mainloop: start\n");
7086       gtk_main ();
7087       g_print ("create_mainloop: done\n");
7088     }
7089   else
7090     gtk_widget_destroy (window);
7091 }
7092
7093 /*
7094  * Main Window and Exit
7095  */
7096
7097 void
7098 do_exit (GtkWidget *widget, GtkWidget *window)
7099 {
7100   gtk_widget_destroy (window);
7101   gtk_main_quit ();
7102 }
7103
7104 void
7105 create_main_window (void)
7106 {
7107   struct {
7108     char *label;
7109     void (*func) ();
7110   } buttons[] =
7111     {
7112       { "button box", create_button_box },
7113       { "buttons", create_buttons },
7114       { "check buttons", create_check_buttons },
7115       { "clist", create_clist},
7116       { "color selection", create_color_selection },
7117       { "ctree", create_ctree },
7118       { "cursors", create_cursors },
7119       { "dialog", create_dialog },
7120       { "dnd", create_dnd },
7121       { "entry", create_entry },
7122       { "file selection", create_file_selection },
7123       { "font selection", create_font_selection },
7124       { "gamma curve", create_gamma_curve },
7125       { "handle box", create_handle_box },
7126       { "list", create_list },
7127       { "menus", create_menus },
7128       { "notebook", create_notebook },
7129       { "panes", create_panes },
7130       { "pixmap", create_pixmap },
7131       { "preview color", create_color_preview },
7132       { "preview gray", create_gray_preview },
7133       { "progress bar", create_progress_bar },
7134       { "radio buttons", create_radio_buttons },
7135       { "range controls", create_range_controls },
7136       { "rc file", create_rc_file },
7137       { "reparent", create_reparent },
7138       { "rulers", create_rulers },
7139       { "scrolled windows", create_scrolled_windows },
7140       { "shapes", create_shapes },
7141       { "spinbutton", create_spins },
7142       { "statusbar", create_statusbar },
7143       { "test idle", create_idle_test },
7144       { "test mainloop", create_mainloop },
7145       { "test scrolling", create_scroll_test },
7146       { "test selection", create_selection_test },
7147       { "test timeout", create_timeout_test },
7148       { "text", create_text },
7149       { "toggle buttons", create_toggle_buttons },
7150       { "toolbar", create_toolbar },
7151       { "tooltips", create_tooltips },
7152       { "tree", create_tree_mode_window},
7153       { "WM hints", create_wmhints },
7154     };
7155   int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
7156   GtkWidget *window;
7157   GtkWidget *box1;
7158   GtkWidget *box2;
7159   GtkWidget *scrolled_window;
7160   GtkWidget *button;
7161   GtkWidget *label;
7162   gchar buffer[64];
7163   GtkWidget *separator;
7164   int i;
7165
7166   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7167   gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
7168   gtk_widget_set_name (window, "main window");
7169   gtk_widget_set_usize (window, 200, 400);
7170   gtk_widget_set_uposition (window, 20, 20);
7171
7172   gtk_signal_connect (GTK_OBJECT (window), "destroy",
7173                       GTK_SIGNAL_FUNC(gtk_main_quit),
7174                       NULL);
7175   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
7176                       GTK_SIGNAL_FUNC (gtk_false),
7177                       NULL);
7178
7179   box1 = gtk_vbox_new (FALSE, 0);
7180   gtk_container_add (GTK_CONTAINER (window), box1);
7181
7182   if (gtk_micro_version > 0)
7183     sprintf (buffer,
7184              "Gtk+ v%d.%d.%d",
7185              gtk_major_version,
7186              gtk_minor_version,
7187              gtk_micro_version);
7188   else
7189     sprintf (buffer,
7190              "Gtk+ v%d.%d",
7191              gtk_major_version,
7192              gtk_minor_version);
7193
7194   label = gtk_label_new (buffer);
7195   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
7196
7197   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
7198   gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
7199   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
7200                                   GTK_POLICY_AUTOMATIC, 
7201                                   GTK_POLICY_AUTOMATIC);
7202   GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (scrolled_window)->vscrollbar, GTK_CAN_FOCUS);
7203   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
7204
7205   box2 = gtk_vbox_new (FALSE, 0);
7206   gtk_container_border_width (GTK_CONTAINER (box2), 10);
7207   gtk_container_add (GTK_CONTAINER (scrolled_window), box2);
7208   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
7209                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
7210   gtk_widget_show (box2);
7211
7212   for (i = 0; i < nbuttons; i++)
7213     {
7214       button = gtk_button_new_with_label (buttons[i].label);
7215       if (buttons[i].func)
7216         gtk_signal_connect (GTK_OBJECT (button), 
7217                             "clicked", 
7218                             GTK_SIGNAL_FUNC(buttons[i].func),
7219                             NULL);
7220       else
7221         gtk_widget_set_sensitive (button, FALSE);
7222       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7223     }
7224
7225   separator = gtk_hseparator_new ();
7226   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7227
7228   box2 = gtk_vbox_new (FALSE, 10);
7229   gtk_container_border_width (GTK_CONTAINER (box2), 10);
7230   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7231
7232   button = gtk_button_new_with_label ("close");
7233   gtk_signal_connect (GTK_OBJECT (button), "clicked",
7234                       GTK_SIGNAL_FUNC (do_exit),
7235                       window);
7236   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7237   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7238   gtk_widget_grab_default (button);
7239
7240   gtk_widget_show_all (window);
7241 }
7242
7243 #ifdef HAVE_LIBGLE
7244 #include <gle/gle.h>
7245 #endif /* !HAVE_LIBGLE */
7246
7247 int
7248 main (int argc, char *argv[])
7249 {
7250   GtkBindingSet *binding_set;
7251
7252   srand (time (NULL));
7253
7254   gtk_set_locale ();
7255
7256   gtk_init (&argc, &argv);
7257
7258 #ifdef HAVE_LIBGLE
7259   gle_init (&argc, &argv);
7260 #endif /* !HAVE_LIBGLE */
7261
7262   /* bindings test
7263    */
7264   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
7265   gtk_binding_entry_add_signal (binding_set,
7266                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
7267                                 "debug_msg",
7268                                 1,
7269                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
7270
7271   gtk_rc_parse ("testgtkrc");
7272
7273   create_main_window ();
7274
7275   gtk_main ();
7276
7277   return 0;
7278 }