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