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