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