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