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