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