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