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