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