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