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