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