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