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