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