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