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