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