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