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