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