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