]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
don't reduce the scroll rect size by the scroll amount
[~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("../gtk/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  * Paned keyboard navigation
7907  */
7908
7909 static GtkWidget*
7910 paned_keyboard_window1 (void)
7911 {
7912   GtkWidget *window1;
7913   GtkWidget *hpaned1;
7914   GtkWidget *frame1;
7915   GtkWidget *vbox1;
7916   GtkWidget *button7;
7917   GtkWidget *button8;
7918   GtkWidget *button9;
7919   GtkWidget *vpaned1;
7920   GtkWidget *frame2;
7921   GtkWidget *frame5;
7922   GtkWidget *hbox1;
7923   GtkWidget *button5;
7924   GtkWidget *button6;
7925   GtkWidget *frame3;
7926   GtkWidget *frame4;
7927   GtkWidget *table1;
7928   GtkWidget *button1;
7929   GtkWidget *button2;
7930   GtkWidget *button3;
7931   GtkWidget *button4;
7932
7933   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7934   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
7935
7936   hpaned1 = gtk_hpaned_new ();
7937   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
7938
7939   frame1 = gtk_frame_new (NULL);
7940   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
7941   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
7942
7943   vbox1 = gtk_vbox_new (FALSE, 0);
7944   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
7945
7946   button7 = gtk_button_new_with_label ("button7");
7947   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
7948
7949   button8 = gtk_button_new_with_label ("button8");
7950   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
7951
7952   button9 = gtk_button_new_with_label ("button9");
7953   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
7954
7955   vpaned1 = gtk_vpaned_new ();
7956   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
7957
7958   frame2 = gtk_frame_new (NULL);
7959   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
7960   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
7961
7962   frame5 = gtk_frame_new (NULL);
7963   gtk_container_add (GTK_CONTAINER (frame2), frame5);
7964
7965   hbox1 = gtk_hbox_new (FALSE, 0);
7966   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
7967
7968   button5 = gtk_button_new_with_label ("button5");
7969   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
7970
7971   button6 = gtk_button_new_with_label ("button6");
7972   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
7973
7974   frame3 = gtk_frame_new (NULL);
7975   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
7976   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
7977
7978   frame4 = gtk_frame_new ("Buttons");
7979   gtk_container_add (GTK_CONTAINER (frame3), frame4);
7980   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
7981
7982   table1 = gtk_table_new (2, 2, FALSE);
7983   gtk_container_add (GTK_CONTAINER (frame4), table1);
7984   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
7985
7986   button1 = gtk_button_new_with_label ("button1");
7987   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
7988                     (GtkAttachOptions) (GTK_FILL),
7989                     (GtkAttachOptions) (0), 0, 0);
7990
7991   button2 = gtk_button_new_with_label ("button2");
7992   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
7993                     (GtkAttachOptions) (GTK_FILL),
7994                     (GtkAttachOptions) (0), 0, 0);
7995
7996   button3 = gtk_button_new_with_label ("button3");
7997   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
7998                     (GtkAttachOptions) (GTK_FILL),
7999                     (GtkAttachOptions) (0), 0, 0);
8000
8001   button4 = gtk_button_new_with_label ("button4");
8002   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
8003                     (GtkAttachOptions) (GTK_FILL),
8004                     (GtkAttachOptions) (0), 0, 0);
8005
8006   return window1;
8007 }
8008
8009 static GtkWidget*
8010 paned_keyboard_window2 (void)
8011 {
8012   GtkWidget *window2;
8013   GtkWidget *hpaned2;
8014   GtkWidget *frame6;
8015   GtkWidget *button13;
8016   GtkWidget *hbox2;
8017   GtkWidget *vpaned2;
8018   GtkWidget *frame7;
8019   GtkWidget *button12;
8020   GtkWidget *frame8;
8021   GtkWidget *button11;
8022   GtkWidget *button10;
8023
8024   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8025   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
8026
8027   hpaned2 = gtk_hpaned_new ();
8028   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
8029
8030   frame6 = gtk_frame_new (NULL);
8031   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
8032   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
8033
8034   button13 = gtk_button_new_with_label ("button13");
8035   gtk_container_add (GTK_CONTAINER (frame6), button13);
8036
8037   hbox2 = gtk_hbox_new (FALSE, 0);
8038   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
8039
8040   vpaned2 = gtk_vpaned_new ();
8041   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
8042
8043   frame7 = gtk_frame_new (NULL);
8044   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
8045   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
8046
8047   button12 = gtk_button_new_with_label ("button12");
8048   gtk_container_add (GTK_CONTAINER (frame7), button12);
8049
8050   frame8 = gtk_frame_new (NULL);
8051   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
8052   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
8053
8054   button11 = gtk_button_new_with_label ("button11");
8055   gtk_container_add (GTK_CONTAINER (frame8), button11);
8056
8057   button10 = gtk_button_new_with_label ("button10");
8058   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
8059
8060   return window2;
8061 }
8062
8063 static GtkWidget*
8064 paned_keyboard_window3 (void)
8065 {
8066   GtkWidget *window3;
8067   GtkWidget *vbox2;
8068   GtkWidget *label1;
8069   GtkWidget *hpaned3;
8070   GtkWidget *frame9;
8071   GtkWidget *button14;
8072   GtkWidget *hpaned4;
8073   GtkWidget *frame10;
8074   GtkWidget *button15;
8075   GtkWidget *hpaned5;
8076   GtkWidget *frame11;
8077   GtkWidget *button16;
8078   GtkWidget *frame12;
8079   GtkWidget *button17;
8080
8081   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8082   gtk_object_set_data (GTK_OBJECT (window3), "window3", window3);
8083   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
8084
8085   vbox2 = gtk_vbox_new (FALSE, 0);
8086   gtk_container_add (GTK_CONTAINER (window3), vbox2);
8087
8088   label1 = gtk_label_new ("Three panes nested inside each other");
8089   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
8090
8091   hpaned3 = gtk_hpaned_new ();
8092   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
8093
8094   frame9 = gtk_frame_new (NULL);
8095   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
8096   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
8097
8098   button14 = gtk_button_new_with_label ("button14");
8099   gtk_container_add (GTK_CONTAINER (frame9), button14);
8100
8101   hpaned4 = gtk_hpaned_new ();
8102   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
8103
8104   frame10 = gtk_frame_new (NULL);
8105   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
8106   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
8107
8108   button15 = gtk_button_new_with_label ("button15");
8109   gtk_container_add (GTK_CONTAINER (frame10), button15);
8110
8111   hpaned5 = gtk_hpaned_new ();
8112   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
8113
8114   frame11 = gtk_frame_new (NULL);
8115   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
8116   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
8117
8118   button16 = gtk_button_new_with_label ("button16");
8119   gtk_container_add (GTK_CONTAINER (frame11), button16);
8120
8121   frame12 = gtk_frame_new (NULL);
8122   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
8123   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
8124
8125   button17 = gtk_button_new_with_label ("button17");
8126   gtk_container_add (GTK_CONTAINER (frame12), button17);
8127
8128   return window3;
8129 }
8130
8131 static GtkWidget*
8132 paned_keyboard_window4 (void)
8133 {
8134   GtkWidget *window4;
8135   GtkWidget *vbox3;
8136   GtkWidget *label2;
8137   GtkWidget *hpaned6;
8138   GtkWidget *vpaned3;
8139   GtkWidget *button19;
8140   GtkWidget *button18;
8141   GtkWidget *hbox3;
8142   GtkWidget *vpaned4;
8143   GtkWidget *button21;
8144   GtkWidget *button20;
8145   GtkWidget *vpaned5;
8146   GtkWidget *button23;
8147   GtkWidget *button22;
8148   GtkWidget *vpaned6;
8149   GtkWidget *button25;
8150   GtkWidget *button24;
8151
8152   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8153   gtk_object_set_data (GTK_OBJECT (window4), "window4", window4);
8154   gtk_window_set_title (GTK_WINDOW (window4), "window4");
8155
8156   vbox3 = gtk_vbox_new (FALSE, 0);
8157   gtk_container_add (GTK_CONTAINER (window4), vbox3);
8158
8159   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
8160   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
8161   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
8162
8163   hpaned6 = gtk_hpaned_new ();
8164   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
8165
8166   vpaned3 = gtk_vpaned_new ();
8167   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
8168
8169   button19 = gtk_button_new_with_label ("button19");
8170   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
8171
8172   button18 = gtk_button_new_with_label ("button18");
8173   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
8174
8175   hbox3 = gtk_hbox_new (FALSE, 0);
8176   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
8177
8178   vpaned4 = gtk_vpaned_new ();
8179   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
8180
8181   button21 = gtk_button_new_with_label ("button21");
8182   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
8183
8184   button20 = gtk_button_new_with_label ("button20");
8185   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
8186
8187   vpaned5 = gtk_vpaned_new ();
8188   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
8189
8190   button23 = gtk_button_new_with_label ("button23");
8191   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
8192
8193   button22 = gtk_button_new_with_label ("button22");
8194   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
8195
8196   vpaned6 = gtk_vpaned_new ();
8197   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
8198
8199   button25 = gtk_button_new_with_label ("button25");
8200   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
8201
8202   button24 = gtk_button_new_with_label ("button24");
8203   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
8204
8205   return window4;
8206 }
8207
8208 static void
8209 create_paned_keyboard_navigation (void)
8210 {
8211   static GtkWidget *window1 = NULL;
8212   static GtkWidget *window2 = NULL;
8213   static GtkWidget *window3 = NULL;
8214   static GtkWidget *window4 = NULL;
8215
8216   if (!window1)
8217     {
8218       window1 = paned_keyboard_window1 ();
8219       gtk_signal_connect (GTK_OBJECT (window1), "destroy",
8220                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8221                           &window1);
8222     }
8223
8224   if (!window2)
8225     {
8226       window2 = paned_keyboard_window2 ();
8227       gtk_signal_connect (GTK_OBJECT (window2), "destroy",
8228                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8229                           &window2);
8230     }
8231
8232   if (!window3)
8233     {
8234       window3 = paned_keyboard_window3 ();
8235       gtk_signal_connect (GTK_OBJECT (window3), "destroy",
8236                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8237                           &window3);
8238     }
8239
8240   if (!window4)
8241     {
8242       window4 = paned_keyboard_window4 ();
8243       gtk_signal_connect (GTK_OBJECT (window4), "destroy",
8244                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8245                           &window4);
8246     }
8247
8248   if (GTK_WIDGET_VISIBLE (window1))
8249     gtk_widget_destroy (GTK_WIDGET (window1));
8250   else
8251     gtk_widget_show_all (GTK_WIDGET (window1));
8252
8253   if (GTK_WIDGET_VISIBLE (window2))
8254     gtk_widget_destroy (GTK_WIDGET (window2));
8255   else
8256     gtk_widget_show_all (GTK_WIDGET (window2));
8257
8258   if (GTK_WIDGET_VISIBLE (window3))
8259     gtk_widget_destroy (GTK_WIDGET (window3));
8260   else
8261     gtk_widget_show_all (GTK_WIDGET (window3));
8262
8263   if (GTK_WIDGET_VISIBLE (window4))
8264     gtk_widget_destroy (GTK_WIDGET (window4));
8265   else
8266     gtk_widget_show_all (GTK_WIDGET (window4));
8267 }
8268
8269
8270 /*
8271  * Shaped Windows
8272  */
8273
8274 typedef struct _cursoroffset {gint x,y;} CursorOffset;
8275
8276 static void
8277 shape_pressed (GtkWidget *widget, GdkEventButton *event)
8278 {
8279   CursorOffset *p;
8280
8281   /* ignore double and triple click */
8282   if (event->type != GDK_BUTTON_PRESS)
8283     return;
8284
8285   p = gtk_object_get_user_data (GTK_OBJECT(widget));
8286   p->x = (int) event->x;
8287   p->y = (int) event->y;
8288
8289   gtk_grab_add (widget);
8290   gdk_pointer_grab (widget->window, TRUE,
8291                     GDK_BUTTON_RELEASE_MASK |
8292                     GDK_BUTTON_MOTION_MASK |
8293                     GDK_POINTER_MOTION_HINT_MASK,
8294                     NULL, NULL, 0);
8295 }
8296
8297 static void
8298 shape_released (GtkWidget *widget)
8299 {
8300   gtk_grab_remove (widget);
8301   gdk_pointer_ungrab (0);
8302 }
8303
8304 static void
8305 shape_motion (GtkWidget      *widget, 
8306               GdkEventMotion *event)
8307 {
8308   gint xp, yp;
8309   CursorOffset * p;
8310   GdkModifierType mask;
8311
8312   p = gtk_object_get_user_data (GTK_OBJECT (widget));
8313
8314   /*
8315    * Can't use event->x / event->y here 
8316    * because I need absolute coordinates.
8317    */
8318   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
8319   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
8320 }
8321
8322 GtkWidget *
8323 shape_create_icon (char     *xpm_file,
8324                    gint      x,
8325                    gint      y,
8326                    gint      px,
8327                    gint      py,
8328                    gint      window_type)
8329 {
8330   GtkWidget *window;
8331   GtkWidget *pixmap;
8332   GtkWidget *fixed;
8333   CursorOffset* icon_pos;
8334   GdkGC* gc;
8335   GdkBitmap *gdk_pixmap_mask;
8336   GdkPixmap *gdk_pixmap;
8337   GtkStyle *style;
8338
8339   style = gtk_widget_get_default_style ();
8340   gc = style->black_gc; 
8341
8342   /*
8343    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
8344    */
8345   window = gtk_window_new (window_type);
8346   
8347   fixed = gtk_fixed_new ();
8348   gtk_widget_set_usize (fixed, 100,100);
8349   gtk_container_add (GTK_CONTAINER (window), fixed);
8350   gtk_widget_show (fixed);
8351   
8352   gtk_widget_set_events (window, 
8353                          gtk_widget_get_events (window) |
8354                          GDK_BUTTON_MOTION_MASK |
8355                          GDK_POINTER_MOTION_HINT_MASK |
8356                          GDK_BUTTON_PRESS_MASK);
8357
8358   gtk_widget_realize (window);
8359   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
8360                                            &style->bg[GTK_STATE_NORMAL],
8361                                            xpm_file);
8362
8363   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
8364   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
8365   gtk_widget_show (pixmap);
8366   
8367   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
8368   
8369   gdk_drawable_unref (gdk_pixmap_mask);
8370   gdk_drawable_unref (gdk_pixmap);
8371
8372   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
8373                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
8374   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
8375                       GTK_SIGNAL_FUNC (shape_released),NULL);
8376   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
8377                       GTK_SIGNAL_FUNC (shape_motion),NULL);
8378
8379   icon_pos = g_new (CursorOffset, 1);
8380   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
8381
8382   gtk_widget_set_uposition (window, x, y);
8383   gtk_widget_show (window);
8384   
8385   return window;
8386 }
8387
8388 void 
8389 create_shapes (void)
8390 {
8391   /* Variables used by the Drag/Drop and Shape Window demos */
8392   static GtkWidget *modeller = NULL;
8393   static GtkWidget *sheets = NULL;
8394   static GtkWidget *rings = NULL;
8395   static GtkWidget *with_region = NULL;
8396   
8397   if (!(file_exists ("Modeller.xpm") &&
8398         file_exists ("FilesQueue.xpm") &&
8399         file_exists ("3DRings.xpm")))
8400     return;
8401   
8402
8403   if (!modeller)
8404     {
8405       modeller = shape_create_icon ("Modeller.xpm",
8406                                     440, 140, 0,0, GTK_WINDOW_POPUP);
8407
8408       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
8409                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8410                           &modeller);
8411     }
8412   else
8413     gtk_widget_destroy (modeller);
8414
8415   if (!sheets)
8416     {
8417       sheets = shape_create_icon ("FilesQueue.xpm",
8418                                   580, 170, 0,0, GTK_WINDOW_POPUP);
8419
8420       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
8421                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8422                           &sheets);
8423
8424     }
8425   else
8426     gtk_widget_destroy (sheets);
8427
8428   if (!rings)
8429     {
8430       rings = shape_create_icon ("3DRings.xpm",
8431                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
8432
8433       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
8434                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8435                           &rings);
8436     }
8437   else
8438     gtk_widget_destroy (rings);
8439
8440   if (!with_region)
8441     {
8442       GdkRegion *region;
8443       gint x, y;
8444       
8445       with_region = shape_create_icon ("3DRings.xpm",
8446                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
8447
8448       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
8449       
8450       gtk_signal_connect (GTK_OBJECT (with_region), "destroy",
8451                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8452                           &with_region);
8453
8454       /* reset shape from mask to a region */
8455       x = 0;
8456       y = 0;
8457       region = gdk_region_new ();
8458
8459       while (x < 460)
8460         {
8461           while (y < 270)
8462             {
8463               GdkRectangle rect;
8464               rect.x = x;
8465               rect.y = y;
8466               rect.width = 10;
8467               rect.height = 10;
8468
8469               gdk_region_union_with_rect (region, &rect);
8470               
8471               y += 20;
8472             }
8473           y = 0;
8474           x += 20;
8475         }
8476
8477       gdk_window_shape_combine_region (with_region->window,
8478                                        region,
8479                                        0, 0);
8480     }
8481   else
8482     gtk_widget_destroy (with_region);
8483 }
8484
8485 /*
8486  * WM Hints demo
8487  */
8488
8489 void
8490 create_wmhints (void)
8491 {
8492   static GtkWidget *window = NULL;
8493   GtkWidget *label;
8494   GtkWidget *separator;
8495   GtkWidget *button;
8496   GtkWidget *box1;
8497   GtkWidget *box2;
8498
8499   GdkBitmap *circles;
8500
8501   if (!window)
8502     {
8503       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8504
8505       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8506                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8507                           &window);
8508
8509       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
8510       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8511
8512       gtk_widget_realize (window);
8513       
8514       circles = gdk_bitmap_create_from_data (window->window,
8515                                              circles_bits,
8516                                              circles_width,
8517                                              circles_height);
8518       gdk_window_set_icon (window->window, NULL,
8519                            circles, circles);
8520       
8521       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
8522   
8523       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
8524       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
8525       
8526       box1 = gtk_vbox_new (FALSE, 0);
8527       gtk_container_add (GTK_CONTAINER (window), box1);
8528       gtk_widget_show (box1);
8529
8530       label = gtk_label_new ("Try iconizing me!");
8531       gtk_widget_set_usize (label, 150, 50);
8532       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
8533       gtk_widget_show (label);
8534
8535
8536       separator = gtk_hseparator_new ();
8537       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
8538       gtk_widget_show (separator);
8539
8540
8541       box2 = gtk_vbox_new (FALSE, 10);
8542       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8543       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8544       gtk_widget_show (box2);
8545
8546
8547       button = gtk_button_new_with_label ("close");
8548
8549       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8550                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8551                                  GTK_OBJECT (window));
8552
8553       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8554       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8555       gtk_widget_grab_default (button);
8556       gtk_widget_show (button);
8557     }
8558
8559   if (!GTK_WIDGET_VISIBLE (window))
8560     gtk_widget_show (window);
8561   else
8562     gtk_widget_destroy (window);
8563 }
8564
8565
8566 /*
8567  * Window state tracking
8568  */
8569
8570 static gint
8571 window_state_callback (GtkWidget *widget,
8572                        GdkEventWindowState *event,
8573                        gpointer data)
8574 {
8575   GtkWidget *label = data;
8576   gchar *msg;
8577
8578   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
8579                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
8580                      "withdrawn" : "not withdrawn", ", ",
8581                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
8582                      "iconified" : "not iconified", ", ",
8583                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
8584                      "sticky" : "not sticky", ", ",
8585                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
8586                      "maximized" : "not maximized",
8587                      NULL);
8588   
8589   gtk_label_set_text (GTK_LABEL (label), msg);
8590
8591   g_free (msg);
8592
8593   return FALSE;
8594 }
8595
8596 static GtkWidget*
8597 tracking_label (GtkWidget *window)
8598 {
8599   GtkWidget *label;
8600   GtkWidget *hbox;
8601   GtkWidget *button;
8602
8603   hbox = gtk_hbox_new (FALSE, 5);
8604
8605   gtk_signal_connect_object (GTK_OBJECT (hbox),
8606                              "destroy",
8607                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
8608                              GTK_OBJECT (window));
8609   
8610   label = gtk_label_new ("<no window state events received>");
8611   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
8612   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
8613   
8614   gtk_signal_connect (GTK_OBJECT (window),
8615                       "window_state_event",
8616                       GTK_SIGNAL_FUNC (window_state_callback),
8617                       label);
8618
8619   button = gtk_button_new_with_label ("Deiconify");
8620   gtk_signal_connect_object (GTK_OBJECT (button),
8621                              "clicked",
8622                              GTK_SIGNAL_FUNC (gtk_window_deiconify),
8623                              GTK_OBJECT (window));
8624   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
8625
8626   button = gtk_button_new_with_label ("Iconify");
8627   gtk_signal_connect_object (GTK_OBJECT (button),
8628                              "clicked",
8629                              GTK_SIGNAL_FUNC (gtk_window_iconify),
8630                              GTK_OBJECT (window));
8631   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
8632   
8633   button = gtk_button_new_with_label ("Present");
8634   gtk_signal_connect_object (GTK_OBJECT (button),
8635                              "clicked",
8636                              GTK_SIGNAL_FUNC (gtk_window_present),
8637                              GTK_OBJECT (window));
8638   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
8639
8640   button = gtk_button_new_with_label ("Show");
8641   gtk_signal_connect_object (GTK_OBJECT (button),
8642                              "clicked",
8643                              GTK_SIGNAL_FUNC (gtk_widget_show),
8644                              GTK_OBJECT (window));
8645   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
8646   
8647   gtk_widget_show_all (hbox);
8648   
8649   return hbox;
8650 }
8651
8652 static GtkWidget*
8653 get_state_controls (GtkWidget *window)
8654 {
8655   GtkWidget *vbox;
8656   GtkWidget *button;
8657
8658   vbox = gtk_vbox_new (FALSE, 0);
8659   
8660   button = gtk_button_new_with_label ("Stick");
8661   gtk_signal_connect_object (GTK_OBJECT (button),
8662                              "clicked",
8663                              GTK_SIGNAL_FUNC (gtk_window_stick),
8664                              GTK_OBJECT (window));
8665   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8666
8667   button = gtk_button_new_with_label ("Unstick");
8668   gtk_signal_connect_object (GTK_OBJECT (button),
8669                              "clicked",
8670                              GTK_SIGNAL_FUNC (gtk_window_unstick),
8671                              GTK_OBJECT (window));
8672   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8673   
8674   button = gtk_button_new_with_label ("Maximize");
8675   gtk_signal_connect_object (GTK_OBJECT (button),
8676                              "clicked",
8677                              GTK_SIGNAL_FUNC (gtk_window_maximize),
8678                              GTK_OBJECT (window));
8679   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8680
8681   button = gtk_button_new_with_label ("Unmaximize");
8682   gtk_signal_connect_object (GTK_OBJECT (button),
8683                              "clicked",
8684                              GTK_SIGNAL_FUNC (gtk_window_unmaximize),
8685                              GTK_OBJECT (window));
8686   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8687
8688   button = gtk_button_new_with_label ("Iconify");
8689   gtk_signal_connect_object (GTK_OBJECT (button),
8690                              "clicked",
8691                              GTK_SIGNAL_FUNC (gtk_window_iconify),
8692                              GTK_OBJECT (window));
8693   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8694
8695   button = gtk_button_new_with_label ("Hide (withdraw)");
8696   gtk_signal_connect_object (GTK_OBJECT (button),
8697                              "clicked",
8698                              GTK_SIGNAL_FUNC (gtk_widget_hide),
8699                              GTK_OBJECT (window));
8700   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
8701   
8702   gtk_widget_show_all (vbox);
8703
8704   return vbox;
8705 }
8706
8707 void
8708 create_window_states (void)
8709 {
8710   static GtkWidget *window = NULL;
8711   GtkWidget *label;
8712   GtkWidget *box1;
8713   GtkWidget *iconified;
8714   GtkWidget *normal;
8715   GtkWidget *controls;
8716   
8717   if (!window)
8718     {
8719       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8720
8721       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8722                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8723                           &window);
8724
8725       gtk_window_set_title (GTK_WINDOW (window), "Window states");
8726       
8727       box1 = gtk_vbox_new (FALSE, 0);
8728       gtk_container_add (GTK_CONTAINER (window), box1);
8729
8730       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8731       gtk_signal_connect_object (GTK_OBJECT (iconified), "destroy",
8732                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8733                                  GTK_OBJECT (window));
8734       gtk_window_iconify (GTK_WINDOW (iconified));
8735       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
8736       controls = get_state_controls (iconified);
8737       gtk_container_add (GTK_CONTAINER (iconified), controls);
8738       
8739       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8740       gtk_signal_connect_object (GTK_OBJECT (normal), "destroy",
8741                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
8742                                  GTK_OBJECT (window));
8743       
8744       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
8745       controls = get_state_controls (normal);
8746       gtk_container_add (GTK_CONTAINER (normal), controls);
8747       
8748       label = tracking_label (iconified);
8749       gtk_container_add (GTK_CONTAINER (box1), label);
8750
8751       label = tracking_label (normal);
8752       gtk_container_add (GTK_CONTAINER (box1), label);
8753
8754       gtk_widget_show_all (iconified);
8755       gtk_widget_show_all (normal);
8756       gtk_widget_show_all (box1);
8757     }
8758
8759   if (!GTK_WIDGET_VISIBLE (window))
8760     gtk_widget_show (window);
8761   else
8762     gtk_widget_destroy (window);
8763 }
8764
8765 /*
8766  * Window sizing
8767  */
8768
8769 static gint
8770 configure_event_callback (GtkWidget *widget,
8771                           GdkEventConfigure *event,
8772                           gpointer data)
8773 {
8774   GtkWidget *label = data;
8775   gchar *msg;
8776   gint x, y;
8777   
8778   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
8779   
8780   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
8781                          "position: %d, %d",
8782                          event->x, event->y, event->width, event->height,
8783                          x, y);
8784   
8785   gtk_label_set_text (GTK_LABEL (label), msg);
8786
8787   g_free (msg);
8788
8789   return FALSE;
8790 }
8791
8792 static void
8793 get_ints (GtkWidget *window,
8794           gint      *a,
8795           gint      *b)
8796 {
8797   GtkWidget *spin1;
8798   GtkWidget *spin2;
8799
8800   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
8801   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
8802
8803   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
8804   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
8805 }
8806
8807 static void
8808 set_size_callback (GtkWidget *widget,
8809                    gpointer   data)
8810 {
8811   gint w, h;
8812   
8813   get_ints (data, &w, &h);
8814
8815   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
8816 }
8817
8818 static void
8819 unset_default_size_callback (GtkWidget *widget,
8820                              gpointer   data)
8821 {
8822   gtk_window_set_default_size (g_object_get_data (data, "target"),
8823                                -1, -1);
8824 }
8825
8826 static void
8827 set_default_size_callback (GtkWidget *widget,
8828                            gpointer   data)
8829 {
8830   gint w, h;
8831   
8832   get_ints (data, &w, &h);
8833
8834   gtk_window_set_default_size (g_object_get_data (data, "target"),
8835                                w, h);
8836 }
8837
8838 static void
8839 unset_usize_callback (GtkWidget *widget,
8840                       gpointer   data)
8841 {
8842   gtk_widget_set_size_request (g_object_get_data (data, "target"),
8843                                -1, -1);
8844 }
8845
8846 static void
8847 set_usize_callback (GtkWidget *widget,
8848                     gpointer   data)
8849 {
8850   gint w, h;
8851   
8852   get_ints (data, &w, &h);
8853
8854   gtk_widget_set_size_request (g_object_get_data (data, "target"),
8855                                w, h);
8856 }
8857
8858 static void
8859 set_location_callback (GtkWidget *widget,
8860                        gpointer   data)
8861 {
8862   gint x, y;
8863   
8864   get_ints (data, &x, &y);
8865
8866   gtk_window_move (g_object_get_data (data, "target"), x, y);
8867 }
8868
8869 static void
8870 move_to_position_callback (GtkWidget *widget,
8871                            gpointer   data)
8872 {
8873   gint x, y;
8874   GtkWindow *window;
8875
8876   window = g_object_get_data (data, "target");
8877   
8878   gtk_window_get_position (window, &x, &y);
8879
8880   gtk_window_move (window, x, y);
8881 }
8882
8883 static void
8884 set_geometry_callback (GtkWidget *entry,
8885                        gpointer   data)
8886 {
8887   gchar *text;
8888   GtkWindow *target;
8889
8890   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
8891   
8892   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
8893
8894   if (!gtk_window_parse_geometry (target, text))
8895     g_print ("Bad geometry string '%s'\n", text);
8896
8897   g_free (text);
8898 }
8899
8900 static void
8901 allow_shrink_callback (GtkWidget *widget,
8902                        gpointer   data)
8903 {
8904   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
8905                 "allow_shrink",
8906                 GTK_TOGGLE_BUTTON (widget)->active,
8907                 NULL);
8908 }
8909
8910 static void
8911 allow_grow_callback (GtkWidget *widget,
8912                      gpointer   data)
8913 {
8914   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
8915                 "allow_grow",
8916                 GTK_TOGGLE_BUTTON (widget)->active,
8917                 NULL);
8918 }
8919
8920 static void
8921 auto_shrink_callback (GtkWidget *widget,
8922                       gpointer   data)
8923 {
8924   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
8925                 "auto_shrink",
8926                 GTK_TOGGLE_BUTTON (widget)->active,
8927                 NULL);
8928 }
8929
8930 static void
8931 gravity_selected (GtkWidget *widget,
8932                   gpointer   data)
8933 {
8934   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
8935                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
8936 }
8937
8938 static void
8939 pos_selected (GtkWidget *widget,
8940               gpointer   data)
8941 {
8942   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
8943                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
8944 }
8945
8946 static void
8947 move_gravity_window_to_current_position (GtkWidget *widget,
8948                                          gpointer   data)
8949 {
8950   gint x, y;
8951   GtkWindow *window;
8952
8953   window = GTK_WINDOW (data);    
8954   
8955   gtk_window_get_position (window, &x, &y);
8956
8957   gtk_window_move (window, x, y);
8958 }
8959
8960 static void
8961 get_screen_corner (GtkWindow *window,
8962                    gint      *x,
8963                    gint      *y)
8964 {
8965   int w, h;
8966   
8967   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
8968
8969   switch (gtk_window_get_gravity (window))
8970     {
8971     case GDK_GRAVITY_SOUTH_EAST:
8972       *x = gdk_screen_width () - w;
8973       *y = gdk_screen_height () - h;
8974       break;
8975
8976     case GDK_GRAVITY_NORTH_EAST:
8977       *x = gdk_screen_width () - w;
8978       *y = 0;
8979       break;
8980
8981     case GDK_GRAVITY_SOUTH_WEST:
8982       *x = 0;
8983       *y = gdk_screen_height () - h;
8984       break;
8985
8986     case GDK_GRAVITY_NORTH_WEST:
8987       *x = 0;
8988       *y = 0;
8989       break;
8990       
8991     case GDK_GRAVITY_SOUTH:
8992       *x = (gdk_screen_width () - w) / 2;
8993       *y = gdk_screen_height () - h;
8994       break;
8995
8996     case GDK_GRAVITY_NORTH:
8997       *x = (gdk_screen_width () - w) / 2;
8998       *y = 0;
8999       break;
9000
9001     case GDK_GRAVITY_WEST:
9002       *x = 0;
9003       *y = (gdk_screen_height () - h) / 2;
9004       break;
9005
9006     case GDK_GRAVITY_EAST:
9007       *x = gdk_screen_width () - w;
9008       *y = (gdk_screen_height () - h) / 2;
9009       break;
9010
9011     case GDK_GRAVITY_CENTER:
9012       *x = (gdk_screen_width () - w) / 2;
9013       *y = (gdk_screen_height () - h) / 2;
9014       break;
9015
9016     case GDK_GRAVITY_STATIC:
9017       /* pick some random numbers */
9018       *x = 350;
9019       *y = 350;
9020       break;
9021
9022     default:
9023       g_assert_not_reached ();
9024       break;
9025     }
9026 }
9027
9028 static void
9029 move_gravity_window_to_starting_position (GtkWidget *widget,
9030                                           gpointer   data)
9031 {
9032   gint x, y;
9033   GtkWindow *window;
9034
9035   window = GTK_WINDOW (data);    
9036   
9037   get_screen_corner (window,
9038                      &x, &y);
9039   
9040   gtk_window_move (window, x, y);
9041 }
9042
9043 static GtkWidget*
9044 make_gravity_window (GtkWidget   *destroy_with,
9045                      GdkGravity   gravity,
9046                      const gchar *title)
9047 {
9048   GtkWidget *window;
9049   GtkWidget *button;
9050   GtkWidget *vbox;
9051   int x, y;
9052   
9053   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9054
9055   vbox = gtk_vbox_new (FALSE, 0);
9056   gtk_widget_show (vbox);
9057   
9058   gtk_container_add (GTK_CONTAINER (window), vbox);
9059   gtk_window_set_title (GTK_WINDOW (window), title);
9060   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
9061
9062   gtk_signal_connect_object (GTK_OBJECT (destroy_with),
9063                              "destroy",
9064                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9065                              GTK_OBJECT (window));
9066
9067   
9068   button = gtk_button_new_with_mnemonic ("_Move to current position");
9069
9070   g_signal_connect (G_OBJECT (button), "clicked",
9071                     G_CALLBACK (move_gravity_window_to_current_position),
9072                     window);
9073
9074   gtk_container_add (GTK_CONTAINER (vbox), button);
9075   gtk_widget_show (button);
9076
9077   button = gtk_button_new_with_mnemonic ("Move to _starting position");
9078
9079   g_signal_connect (G_OBJECT (button), "clicked",
9080                     G_CALLBACK (move_gravity_window_to_starting_position),
9081                     window);
9082
9083   gtk_container_add (GTK_CONTAINER (vbox), button);
9084   gtk_widget_show (button);
9085   
9086   /* Pretend this is the result of --geometry.
9087    * DO NOT COPY THIS CODE unless you are setting --geometry results,
9088    * and in that case you probably should just use gtk_window_parse_geometry().
9089    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
9090    * you are parsing --geometry or equivalent.
9091    */
9092   gtk_window_set_geometry_hints (GTK_WINDOW (window),
9093                                  NULL, NULL,
9094                                  GDK_HINT_USER_POS);
9095
9096   gtk_window_set_default_size (GTK_WINDOW (window),
9097                                200, 200);
9098
9099   get_screen_corner (GTK_WINDOW (window), &x, &y);
9100   
9101   gtk_window_move (GTK_WINDOW (window),
9102                    x, y);
9103   
9104   return window;
9105 }
9106
9107 static void
9108 do_gravity_test (GtkWidget *widget,
9109                  gpointer   data)
9110 {
9111   GtkWidget *destroy_with = data;
9112   GtkWidget *window;
9113   
9114   /* We put a window at each gravity point on the screen. */
9115   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
9116                                 "NorthWest");
9117   gtk_widget_show (window);
9118   
9119   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
9120                                 "SouthEast");
9121   gtk_widget_show (window);
9122
9123   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
9124                                 "NorthEast");
9125   gtk_widget_show (window);
9126
9127   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
9128                                 "SouthWest");
9129   gtk_widget_show (window);
9130
9131   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
9132                                 "South");
9133   gtk_widget_show (window);
9134
9135   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
9136                                 "North");
9137   gtk_widget_show (window);
9138
9139   
9140   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
9141                                 "West");
9142   gtk_widget_show (window);
9143
9144     
9145   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
9146                                 "East");
9147   gtk_widget_show (window);
9148
9149   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
9150                                 "Center");
9151   gtk_widget_show (window);
9152
9153   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
9154                                 "Static");
9155   gtk_widget_show (window);
9156 }
9157
9158 static GtkWidget*
9159 window_controls (GtkWidget *window)
9160 {
9161   GtkWidget *control_window;
9162   GtkWidget *label;
9163   GtkWidget *vbox;
9164   GtkWidget *button;
9165   GtkWidget *spin;
9166   GtkAdjustment *adj;
9167   GtkWidget *entry;
9168   GtkWidget *om;
9169   GtkWidget *menu;
9170   gint i;
9171   
9172   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9173
9174   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
9175   
9176   g_object_set_data (G_OBJECT (control_window),
9177                      "target",
9178                      window);
9179   
9180   gtk_signal_connect_object (GTK_OBJECT (control_window),
9181                              "destroy",
9182                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9183                              GTK_OBJECT (window));
9184
9185   vbox = gtk_vbox_new (FALSE, 5);
9186   
9187   gtk_container_add (GTK_CONTAINER (control_window), vbox);
9188   
9189   label = gtk_label_new ("<no configure events>");
9190   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9191   
9192   gtk_signal_connect (GTK_OBJECT (window),
9193                       "configure_event",
9194                       GTK_SIGNAL_FUNC (configure_event_callback),
9195                       label);
9196
9197   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9198                                               5.0, 0.0);
9199   spin = gtk_spin_button_new (adj, 0, 0);
9200
9201   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9202
9203   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
9204
9205   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9206                                               5.0, 0.0);
9207   spin = gtk_spin_button_new (adj, 0, 0);
9208
9209   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9210
9211   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
9212
9213   entry = gtk_entry_new ();
9214   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9215
9216   gtk_signal_connect (GTK_OBJECT (entry), "changed",
9217                       GTK_SIGNAL_FUNC (set_geometry_callback),
9218                       control_window);
9219
9220   button = gtk_button_new_with_label ("Show gravity test windows");
9221   gtk_signal_connect_object (GTK_OBJECT (button),
9222                              "clicked",
9223                              GTK_SIGNAL_FUNC (do_gravity_test),
9224                              control_window);
9225   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9226
9227   button = gtk_button_new_with_label ("Reshow with initial size");
9228   gtk_signal_connect_object (GTK_OBJECT (button),
9229                              "clicked",
9230                              GTK_SIGNAL_FUNC (gtk_window_reshow_with_initial_size),
9231                              GTK_OBJECT (window));
9232   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9233   
9234   button = gtk_button_new_with_label ("Queue resize");
9235   gtk_signal_connect_object (GTK_OBJECT (button),
9236                              "clicked",
9237                              GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
9238                              GTK_OBJECT (window));
9239   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9240   
9241   button = gtk_button_new_with_label ("Resize");
9242   gtk_signal_connect (GTK_OBJECT (button),
9243                       "clicked",
9244                       GTK_SIGNAL_FUNC (set_size_callback),
9245                       GTK_OBJECT (control_window));
9246   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9247
9248   button = gtk_button_new_with_label ("Set default size");
9249   gtk_signal_connect (GTK_OBJECT (button),
9250                       "clicked",
9251                       GTK_SIGNAL_FUNC (set_default_size_callback),
9252                       GTK_OBJECT (control_window));
9253   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9254
9255   button = gtk_button_new_with_label ("Unset default size");
9256   gtk_signal_connect (GTK_OBJECT (button),
9257                       "clicked",
9258                       GTK_SIGNAL_FUNC (unset_default_size_callback),
9259                       GTK_OBJECT (control_window));
9260   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9261   
9262   button = gtk_button_new_with_label ("Set size request");
9263   gtk_signal_connect (GTK_OBJECT (button),
9264                       "clicked",
9265                       GTK_SIGNAL_FUNC (set_usize_callback),
9266                       GTK_OBJECT (control_window));
9267   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9268
9269   button = gtk_button_new_with_label ("Unset size request");
9270   gtk_signal_connect (GTK_OBJECT (button),
9271                       "clicked",
9272                       GTK_SIGNAL_FUNC (unset_usize_callback),
9273                       GTK_OBJECT (control_window));
9274   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9275   
9276   button = gtk_button_new_with_label ("Move");
9277   gtk_signal_connect (GTK_OBJECT (button),
9278                       "clicked",
9279                       GTK_SIGNAL_FUNC (set_location_callback),
9280                       GTK_OBJECT (control_window));
9281   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9282
9283   button = gtk_button_new_with_label ("Move to current position");
9284   gtk_signal_connect (GTK_OBJECT (button),
9285                       "clicked",
9286                       GTK_SIGNAL_FUNC (move_to_position_callback),
9287                       GTK_OBJECT (control_window));
9288   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9289   
9290   button = gtk_check_button_new_with_label ("Allow shrink");
9291   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9292   gtk_signal_connect (GTK_OBJECT (button),
9293                       "toggled",
9294                       GTK_SIGNAL_FUNC (allow_shrink_callback),
9295                       GTK_OBJECT (control_window));
9296   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9297
9298   button = gtk_check_button_new_with_label ("Allow grow");
9299   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
9300   gtk_signal_connect (GTK_OBJECT (button),
9301                       "toggled",
9302                       GTK_SIGNAL_FUNC (allow_grow_callback),
9303                       GTK_OBJECT (control_window));
9304   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9305   
9306   button = gtk_check_button_new_with_label ("Auto shrink");
9307   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9308   gtk_signal_connect (GTK_OBJECT (button),
9309                       "toggled",
9310                       GTK_SIGNAL_FUNC (auto_shrink_callback),
9311                       GTK_OBJECT (control_window));
9312   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9313
9314   button = gtk_button_new_with_mnemonic ("_Show");
9315   gtk_signal_connect_object (GTK_OBJECT (button),
9316                              "clicked",
9317                              GTK_SIGNAL_FUNC (gtk_widget_show),
9318                              GTK_OBJECT (window));
9319   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9320
9321   button = gtk_button_new_with_mnemonic ("_Hide");
9322   gtk_signal_connect_object (GTK_OBJECT (button),
9323                              "clicked",
9324                              GTK_SIGNAL_FUNC (gtk_widget_hide),
9325                              GTK_OBJECT (window));
9326   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9327   
9328   menu = gtk_menu_new ();
9329   
9330   i = 0;
9331   while (i < 10)
9332     {
9333       GtkWidget *mi;
9334       static gchar *names[] = {
9335         "GDK_GRAVITY_NORTH_WEST",
9336         "GDK_GRAVITY_NORTH",
9337         "GDK_GRAVITY_NORTH_EAST",
9338         "GDK_GRAVITY_WEST",
9339         "GDK_GRAVITY_CENTER",
9340         "GDK_GRAVITY_EAST",
9341         "GDK_GRAVITY_SOUTH_WEST",
9342         "GDK_GRAVITY_SOUTH",
9343         "GDK_GRAVITY_SOUTH_EAST",
9344         "GDK_GRAVITY_STATIC",
9345         NULL
9346       };
9347
9348       g_assert (names[i]);
9349       
9350       mi = gtk_menu_item_new_with_label (names[i]);
9351
9352       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
9353
9354       ++i;
9355     }
9356   
9357   gtk_widget_show_all (menu);
9358   
9359   om = gtk_option_menu_new ();
9360   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
9361   
9362
9363   gtk_signal_connect (GTK_OBJECT (om),
9364                       "changed",
9365                       GTK_SIGNAL_FUNC (gravity_selected),
9366                       control_window);
9367
9368   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
9369
9370
9371   menu = gtk_menu_new ();
9372   
9373   i = 0;
9374   while (i < 5)
9375     {
9376       GtkWidget *mi;
9377       static gchar *names[] = {
9378         "GTK_WIN_POS_NONE",
9379         "GTK_WIN_POS_CENTER",
9380         "GTK_WIN_POS_MOUSE",
9381         "GTK_WIN_POS_CENTER_ALWAYS",
9382         "GTK_WIN_POS_CENTER_ON_PARENT",
9383         NULL
9384       };
9385
9386       g_assert (names[i]);
9387       
9388       mi = gtk_menu_item_new_with_label (names[i]);
9389
9390       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
9391
9392       ++i;
9393     }
9394   
9395   gtk_widget_show_all (menu);
9396   
9397   om = gtk_option_menu_new ();
9398   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
9399   
9400
9401   gtk_signal_connect (GTK_OBJECT (om),
9402                       "changed",
9403                       GTK_SIGNAL_FUNC (pos_selected),
9404                       control_window);
9405
9406   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
9407   
9408   gtk_widget_show_all (vbox);
9409   
9410   return control_window;
9411 }
9412
9413 void
9414 create_window_sizing (void)
9415 {
9416   static GtkWidget *window = NULL;
9417   static GtkWidget *target_window = NULL;
9418   
9419   if (!target_window)
9420     {
9421       GtkWidget *label;
9422       
9423       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9424
9425       label = gtk_label_new (NULL);
9426       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");
9427       gtk_container_add (GTK_CONTAINER (target_window), label);
9428       gtk_widget_show (label);
9429       
9430       gtk_signal_connect (GTK_OBJECT (target_window), "destroy",
9431                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
9432                           &target_window);
9433
9434       window = window_controls (target_window);
9435       
9436       gtk_signal_connect (GTK_OBJECT (window), "destroy",
9437                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
9438                           &window);
9439       
9440       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
9441     }
9442
9443   /* don't show target window by default, we want to allow testing
9444    * of behavior on first show.
9445    */
9446   
9447   if (!GTK_WIDGET_VISIBLE (window))
9448     gtk_widget_show (window);
9449   else
9450     gtk_widget_destroy (window);
9451 }
9452
9453 /*
9454  * GtkProgressBar
9455  */
9456
9457 typedef struct _ProgressData {
9458   GtkWidget *window;
9459   GtkWidget *pbar;
9460   GtkWidget *block_spin;
9461   GtkWidget *x_align_spin;
9462   GtkWidget *y_align_spin;
9463   GtkWidget *step_spin;
9464   GtkWidget *act_blocks_spin;
9465   GtkWidget *label;
9466   GtkWidget *omenu1;
9467   GtkWidget *omenu2;
9468   GtkWidget *entry;
9469   int timer;
9470 } ProgressData;
9471
9472 gint
9473 progress_timeout (gpointer data)
9474 {
9475   gdouble new_val;
9476   GtkAdjustment *adj;
9477
9478   adj = GTK_PROGRESS (data)->adjustment;
9479
9480   new_val = adj->value + 1;
9481   if (new_val > adj->upper)
9482     new_val = adj->lower;
9483
9484   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
9485
9486   return TRUE;
9487 }
9488
9489 static void
9490 destroy_progress (GtkWidget     *widget,
9491                   ProgressData **pdata)
9492 {
9493   gtk_timeout_remove ((*pdata)->timer);
9494   (*pdata)->timer = 0;
9495   (*pdata)->window = NULL;
9496   g_free (*pdata);
9497   *pdata = NULL;
9498 }
9499
9500 static void
9501 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
9502 {
9503   ProgressData *pdata;
9504   gint i;
9505
9506   pdata = (ProgressData *) data;
9507
9508   if (!GTK_WIDGET_MAPPED (widget))
9509     return;
9510
9511   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
9512
9513   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
9514                                     (GtkProgressBarOrientation) i);
9515 }
9516
9517 static void
9518 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
9519 {
9520   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
9521                               GTK_TOGGLE_BUTTON (widget)->active);
9522   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
9523   gtk_widget_set_sensitive (pdata->x_align_spin,
9524                             GTK_TOGGLE_BUTTON (widget)->active);
9525   gtk_widget_set_sensitive (pdata->y_align_spin,
9526                             GTK_TOGGLE_BUTTON (widget)->active);
9527 }
9528
9529 static void
9530 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
9531 {
9532   ProgressData *pdata;
9533   gint i;
9534
9535   pdata = (ProgressData *) data;
9536
9537   if (!GTK_WIDGET_MAPPED (widget))
9538     return;
9539
9540   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
9541
9542   if (i == 1)
9543     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
9544   else
9545     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
9546   
9547   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
9548                                   (GtkProgressBarStyle) i);
9549 }
9550
9551 static void
9552 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
9553 {
9554   char buf[20];
9555
9556   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
9557     sprintf (buf, "???");
9558   else
9559     sprintf (buf, "%.0f%%", 100 *
9560              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
9561   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
9562 }
9563
9564 static void
9565 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
9566 {
9567   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
9568   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
9569      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
9570 }
9571
9572 static void
9573 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
9574 {
9575   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
9576      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
9577 }
9578
9579 static void
9580 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
9581 {
9582   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
9583                gtk_spin_button_get_value_as_int 
9584                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
9585 }
9586
9587 static void
9588 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
9589 {
9590   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
9591          gtk_spin_button_get_value_as_float 
9592                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
9593          gtk_spin_button_get_value_as_float
9594                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
9595 }
9596
9597 static void
9598 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
9599 {
9600   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
9601                                   GTK_TOGGLE_BUTTON (widget)->active);
9602   gtk_widget_set_sensitive (pdata->step_spin, 
9603                             GTK_TOGGLE_BUTTON (widget)->active);
9604   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
9605                             GTK_TOGGLE_BUTTON (widget)->active);
9606 }
9607
9608 static void
9609 entry_changed (GtkWidget *widget, ProgressData *pdata)
9610 {
9611   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
9612                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
9613 }
9614
9615 void
9616 create_progress_bar (void)
9617 {
9618   GtkWidget *button;
9619   GtkWidget *vbox;
9620   GtkWidget *vbox2;
9621   GtkWidget *hbox;
9622   GtkWidget *check;
9623   GtkWidget *frame;
9624   GtkWidget *tab;
9625   GtkWidget *label;
9626   GtkWidget *align;
9627   GtkAdjustment *adj;
9628   static ProgressData *pdata = NULL;
9629
9630   static gchar *items1[] =
9631   {
9632     "Left-Right",
9633     "Right-Left",
9634     "Bottom-Top",
9635     "Top-Bottom"
9636   };
9637
9638   static gchar *items2[] =
9639   {
9640     "Continuous",
9641     "Discrete"
9642   };
9643
9644   if (!pdata)
9645     pdata = g_new0 (ProgressData, 1);
9646
9647   if (!pdata->window)
9648     {
9649       pdata->window = gtk_dialog_new ();
9650
9651       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
9652
9653       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
9654                           GTK_SIGNAL_FUNC (destroy_progress),
9655                           &pdata);
9656
9657       pdata->timer = 0;
9658
9659       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
9660       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
9661
9662       vbox = gtk_vbox_new (FALSE, 5);
9663       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
9664       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
9665                           vbox, FALSE, TRUE, 0);
9666
9667       frame = gtk_frame_new ("Progress");
9668       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
9669
9670       vbox2 = gtk_vbox_new (FALSE, 5);
9671       gtk_container_add (GTK_CONTAINER (frame), vbox2);
9672
9673       align = gtk_alignment_new (0.5, 0.5, 0, 0);
9674       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
9675
9676       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
9677       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9678                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
9679
9680       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
9681       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
9682                                       "%v from [%l,%u] (=%p%%)");
9683       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
9684       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
9685
9686       align = gtk_alignment_new (0.5, 0.5, 0, 0);
9687       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
9688
9689       hbox = gtk_hbox_new (FALSE, 5);
9690       gtk_container_add (GTK_CONTAINER (align), hbox);
9691       label = gtk_label_new ("Label updated by user :"); 
9692       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
9693       pdata->label = gtk_label_new ("");
9694       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
9695
9696       frame = gtk_frame_new ("Options");
9697       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
9698
9699       vbox2 = gtk_vbox_new (FALSE, 5);
9700       gtk_container_add (GTK_CONTAINER (frame), vbox2);
9701
9702       tab = gtk_table_new (7, 2, FALSE);
9703       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
9704
9705       label = gtk_label_new ("Orientation :");
9706       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
9707                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9708                         5, 5);
9709       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
9710
9711       pdata->omenu1 = build_option_menu (items1, 4, 0,
9712                                          progressbar_toggle_orientation,
9713                                          pdata);
9714       hbox = gtk_hbox_new (FALSE, 0);
9715       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
9716                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9717                         5, 5);
9718       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
9719       
9720       check = gtk_check_button_new_with_label ("Show text");
9721       gtk_signal_connect (GTK_OBJECT (check), "clicked",
9722                           GTK_SIGNAL_FUNC (toggle_show_text),
9723                           pdata);
9724       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
9725                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9726                         5, 5);
9727
9728       hbox = gtk_hbox_new (FALSE, 0);
9729       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
9730                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9731                         5, 5);
9732
9733       label = gtk_label_new ("Format : ");
9734       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
9735
9736       pdata->entry = gtk_entry_new ();
9737       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
9738                           GTK_SIGNAL_FUNC (entry_changed),
9739                           pdata);
9740       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
9741       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
9742       gtk_widget_set_usize (pdata->entry, 100, -1);
9743       gtk_widget_set_sensitive (pdata->entry, FALSE);
9744
9745       label = gtk_label_new ("Text align :");
9746       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
9747                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9748                         5, 5);
9749       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
9750
9751       hbox = gtk_hbox_new (FALSE, 0);
9752       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
9753                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9754                         5, 5);
9755
9756       label = gtk_label_new ("x :");
9757       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
9758       
9759       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
9760       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
9761       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9762                           GTK_SIGNAL_FUNC (adjust_align), pdata);
9763       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
9764       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
9765
9766       label = gtk_label_new ("y :");
9767       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
9768
9769       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
9770       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
9771       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9772                           GTK_SIGNAL_FUNC (adjust_align), pdata);
9773       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
9774       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
9775
9776       label = gtk_label_new ("Bar Style :");
9777       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
9778                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9779                         5, 5);
9780       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
9781
9782       pdata->omenu2 = build_option_menu (items2, 2, 0,
9783                                          progressbar_toggle_bar_style,
9784                                          pdata);
9785       hbox = gtk_hbox_new (FALSE, 0);
9786       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
9787                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9788                         5, 5);
9789       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
9790
9791       label = gtk_label_new ("Block count :");
9792       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
9793                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9794                         5, 5);
9795       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
9796
9797       hbox = gtk_hbox_new (FALSE, 0);
9798       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
9799                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9800                         5, 5);
9801       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
9802       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
9803       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9804                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
9805       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
9806       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
9807
9808       check = gtk_check_button_new_with_label ("Activity mode");
9809       gtk_signal_connect (GTK_OBJECT (check), "clicked",
9810                           GTK_SIGNAL_FUNC (toggle_activity_mode),
9811                           pdata);
9812       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
9813                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9814                         5, 5);
9815
9816       hbox = gtk_hbox_new (FALSE, 0);
9817       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
9818                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9819                         5, 5);
9820       label = gtk_label_new ("Step size : ");
9821       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
9822       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
9823       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
9824       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9825                           GTK_SIGNAL_FUNC (adjust_step), pdata);
9826       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
9827       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
9828
9829       hbox = gtk_hbox_new (FALSE, 0);
9830       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
9831                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
9832                         5, 5);
9833       label = gtk_label_new ("Blocks :     ");
9834       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
9835       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
9836       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
9837       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
9838                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
9839       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
9840                           0);
9841       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
9842
9843       button = gtk_button_new_with_label ("close");
9844       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
9845                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
9846                                  GTK_OBJECT (pdata->window));
9847       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9848       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
9849                           button, TRUE, TRUE, 0);
9850       gtk_widget_grab_default (button);
9851     }
9852
9853   if (!GTK_WIDGET_VISIBLE (pdata->window))
9854     gtk_widget_show_all (pdata->window);
9855   else
9856     gtk_widget_destroy (pdata->window);
9857 }
9858
9859 /*
9860  * Properties
9861  */
9862
9863 typedef struct {
9864   int x;
9865   int y;
9866   gboolean found;
9867   gboolean first;
9868   GtkWidget *res_widget;
9869 } FindWidgetData;
9870
9871 static void
9872 find_widget (GtkWidget *widget, FindWidgetData *data)
9873 {
9874   GtkAllocation new_allocation;
9875   gint x_offset = 0;
9876   gint y_offset = 0;
9877
9878   new_allocation = widget->allocation;
9879
9880   if (data->found || !GTK_WIDGET_MAPPED (widget))
9881     return;
9882
9883   /* Note that in the following code, we only count the
9884    * position as being inside a WINDOW widget if it is inside
9885    * widget->window; points that are outside of widget->window
9886    * but within the allocation are not counted. This is consistent
9887    * with the way we highlight drag targets.
9888    */
9889   if (!GTK_WIDGET_NO_WINDOW (widget))
9890     {
9891       new_allocation.x = 0;
9892       new_allocation.y = 0;
9893     }
9894   
9895   if (widget->parent && !data->first)
9896     {
9897       GdkWindow *window = widget->window;
9898       while (window != widget->parent->window)
9899         {
9900           gint tx, ty, twidth, theight;
9901           gdk_window_get_size (window, &twidth, &theight);
9902
9903           if (new_allocation.x < 0)
9904             {
9905               new_allocation.width += new_allocation.x;
9906               new_allocation.x = 0;
9907             }
9908           if (new_allocation.y < 0)
9909             {
9910               new_allocation.height += new_allocation.y;
9911               new_allocation.y = 0;
9912             }
9913           if (new_allocation.x + new_allocation.width > twidth)
9914             new_allocation.width = twidth - new_allocation.x;
9915           if (new_allocation.y + new_allocation.height > theight)
9916             new_allocation.height = theight - new_allocation.y;
9917
9918           gdk_window_get_position (window, &tx, &ty);
9919           new_allocation.x += tx;
9920           x_offset += tx;
9921           new_allocation.y += ty;
9922           y_offset += ty;
9923           
9924           window = gdk_window_get_parent (window);
9925         }
9926     }
9927
9928   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
9929       (data->x < new_allocation.x + new_allocation.width) && 
9930       (data->y < new_allocation.y + new_allocation.height))
9931     {
9932       /* First, check if the drag is in a valid drop site in
9933        * one of our children 
9934        */
9935       if (GTK_IS_CONTAINER (widget))
9936         {
9937           FindWidgetData new_data = *data;
9938           
9939           new_data.x -= x_offset;
9940           new_data.y -= y_offset;
9941           new_data.found = FALSE;
9942           new_data.first = FALSE;
9943           
9944           gtk_container_forall (GTK_CONTAINER (widget),
9945                                 (GtkCallback)find_widget,
9946                                 &new_data);
9947           
9948           data->found = new_data.found;
9949           if (data->found)
9950             data->res_widget = new_data.res_widget;
9951         }
9952
9953       /* If not, and this widget is registered as a drop site, check to
9954        * emit "drag_motion" to check if we are actually in
9955        * a drop site.
9956        */
9957       if (!data->found)
9958         {
9959           data->found = TRUE;
9960           data->res_widget = widget;
9961         }
9962     }
9963 }
9964
9965 static GtkWidget *
9966 find_widget_at_pointer (void)
9967 {
9968   GtkWidget *widget = NULL;
9969   GdkWindow *pointer_window;
9970   gint x, y;
9971   FindWidgetData data;
9972  
9973  pointer_window = gdk_window_at_pointer (NULL, NULL);
9974  
9975  if (pointer_window)
9976    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);
9977
9978  if (widget)
9979    {
9980      gdk_window_get_pointer (widget->window,
9981                              &x, &y, NULL);
9982      
9983      data.x = x;
9984      data.y = y;
9985      data.found = FALSE;
9986      data.first = TRUE;
9987
9988      find_widget (widget, &data);
9989      if (data.found)
9990        return data.res_widget;
9991      return widget;
9992    }
9993  return NULL;
9994 }
9995
9996 struct PropertiesData {
9997   GtkWidget **window;
9998   GdkCursor *cursor;
9999   gboolean in_query;
10000   gint handler;
10001 };
10002
10003 static void
10004 destroy_properties (GtkWidget             *widget,
10005                     struct PropertiesData *data)
10006 {
10007   if (data->window)
10008     {
10009       *data->window = NULL;
10010       data->window = NULL;
10011     }
10012
10013   if (data->cursor)
10014     {
10015       gdk_cursor_destroy (data->cursor);
10016       data->cursor = NULL;
10017     }
10018
10019   if (data->handler)
10020     {
10021       gtk_signal_disconnect (widget, data->handler);
10022       data->handler = 0;
10023     }
10024
10025   g_free (data);
10026 }
10027
10028 static gint
10029 property_query_event (GtkWidget        *widget,
10030                       GdkEvent         *event,
10031                       struct PropertiesData *data)
10032 {
10033   GtkWidget *res_widget = NULL;
10034
10035   if (!data->in_query)
10036     return FALSE;
10037   
10038   if (event->type == GDK_BUTTON_RELEASE)
10039     {
10040       gtk_grab_remove (widget);
10041       gdk_pointer_ungrab (GDK_CURRENT_TIME);
10042       
10043       res_widget = find_widget_at_pointer ();
10044       if (res_widget)
10045         create_prop_editor (G_OBJECT (res_widget), 0);
10046
10047       data->in_query = FALSE;
10048     }
10049   return FALSE;
10050 }
10051
10052
10053 static void
10054 query_properties (GtkButton *button,
10055                   struct PropertiesData *data)
10056 {
10057   gint failure;
10058
10059   gtk_signal_connect (GTK_OBJECT (button), "event",
10060                       (GtkSignalFunc) property_query_event, data);
10061
10062
10063   if (!data->cursor)
10064     data->cursor = gdk_cursor_new (GDK_TARGET);
10065   
10066   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
10067                               TRUE,
10068                               GDK_BUTTON_RELEASE_MASK,
10069                               NULL,
10070                               data->cursor,
10071                               GDK_CURRENT_TIME);
10072
10073   gtk_grab_add (GTK_WIDGET (button));
10074
10075   data->in_query = TRUE;
10076 }
10077
10078 static void
10079 create_properties (void)
10080 {
10081   static GtkWidget *window = NULL;
10082   GtkWidget *button;
10083   GtkWidget *vbox;
10084   GtkWidget *label;
10085   struct PropertiesData *data;
10086
10087   data = g_new (struct PropertiesData, 1);
10088   data->window = &window;
10089   data->in_query = FALSE;
10090   data->cursor = NULL;
10091   data->handler = 0;
10092
10093   if (!window)
10094     {
10095       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10096
10097       data->handler = gtk_signal_connect (GTK_OBJECT (window), "destroy",
10098                                           GTK_SIGNAL_FUNC(destroy_properties),
10099                                           data);
10100
10101       gtk_window_set_title (GTK_WINDOW (window), "test properties");
10102       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10103
10104       vbox = gtk_vbox_new (FALSE, 1);
10105       gtk_container_add (GTK_CONTAINER (window), vbox);
10106             
10107       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
10108       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
10109       
10110       button = gtk_button_new_with_label ("Query properties");
10111       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
10112       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10113                           GTK_SIGNAL_FUNC(query_properties),
10114                           data);
10115     }
10116
10117   if (!GTK_WIDGET_VISIBLE (window))
10118     gtk_widget_show_all (window);
10119   else
10120     gtk_widget_destroy (window);
10121   
10122 }
10123
10124
10125 /*
10126  * Color Preview
10127  */
10128
10129 static int color_idle = 0;
10130
10131 gint
10132 color_idle_func (GtkWidget *preview)
10133 {
10134   static int count = 1;
10135   guchar buf[768];
10136   int i, j, k;
10137
10138   for (i = 0; i < 256; i++)
10139     {
10140       for (j = 0, k = 0; j < 256; j++)
10141         {
10142           buf[k+0] = i + count;
10143           buf[k+1] = 0;
10144           buf[k+2] = j + count;
10145           k += 3;
10146         }
10147
10148       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10149     }
10150
10151   count += 1;
10152
10153   gtk_widget_draw (preview, NULL);
10154
10155   return TRUE;
10156 }
10157
10158 static void
10159 color_preview_destroy (GtkWidget  *widget,
10160                        GtkWidget **window)
10161 {
10162   gtk_idle_remove (color_idle);
10163   color_idle = 0;
10164
10165   *window = NULL;
10166 }
10167
10168 void
10169 create_color_preview (void)
10170 {
10171   static GtkWidget *window = NULL;
10172   GtkWidget *preview;
10173   guchar buf[768];
10174   int i, j, k;
10175
10176   if (!window)
10177     {
10178       gtk_widget_push_colormap (gdk_rgb_get_cmap ());
10179       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10180       gtk_widget_pop_colormap ();
10181
10182       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10183                           GTK_SIGNAL_FUNC(color_preview_destroy),
10184                           &window);
10185
10186       gtk_window_set_title (GTK_WINDOW (window), "test");
10187       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10188
10189       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
10190       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10191       gtk_container_add (GTK_CONTAINER (window), preview);
10192
10193       for (i = 0; i < 256; i++)
10194         {
10195           for (j = 0, k = 0; j < 256; j++)
10196             {
10197               buf[k+0] = i;
10198               buf[k+1] = 0;
10199               buf[k+2] = j;
10200               k += 3;
10201             }
10202
10203           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10204         }
10205
10206       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
10207     }
10208
10209   if (!GTK_WIDGET_VISIBLE (window))
10210     gtk_widget_show_all (window);
10211   else
10212     gtk_widget_destroy (window);
10213 }
10214
10215 /*
10216  * Gray Preview
10217  */
10218
10219 static int gray_idle = 0;
10220
10221 gint
10222 gray_idle_func (GtkWidget *preview)
10223 {
10224   static int count = 1;
10225   guchar buf[256];
10226   int i, j;
10227
10228   for (i = 0; i < 256; i++)
10229     {
10230       for (j = 0; j < 256; j++)
10231         buf[j] = i + j + count;
10232
10233       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10234     }
10235
10236   count += 1;
10237
10238   gtk_widget_draw (preview, NULL);
10239
10240   return TRUE;
10241 }
10242
10243 static void
10244 gray_preview_destroy (GtkWidget  *widget,
10245                       GtkWidget **window)
10246 {
10247   gtk_idle_remove (gray_idle);
10248   gray_idle = 0;
10249
10250   *window = NULL;
10251 }
10252
10253 void
10254 create_gray_preview (void)
10255 {
10256   static GtkWidget *window = NULL;
10257   GtkWidget *preview;
10258   guchar buf[256];
10259   int i, j;
10260
10261   if (!window)
10262     {
10263       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10264
10265       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10266                           GTK_SIGNAL_FUNC(gray_preview_destroy),
10267                           &window);
10268
10269       gtk_window_set_title (GTK_WINDOW (window), "test");
10270       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10271
10272       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
10273       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10274       gtk_container_add (GTK_CONTAINER (window), preview);
10275
10276       for (i = 0; i < 256; i++)
10277         {
10278           for (j = 0; j < 256; j++)
10279             buf[j] = i + j;
10280
10281           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10282         }
10283
10284       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
10285     }
10286
10287   if (!GTK_WIDGET_VISIBLE (window))
10288     gtk_widget_show_all (window);
10289   else
10290     gtk_widget_destroy (window);
10291 }
10292
10293
10294 /*
10295  * Selection Test
10296  */
10297
10298 void
10299 selection_test_received (GtkWidget *list, GtkSelectionData *data)
10300 {
10301   GdkAtom *atoms;
10302   GtkWidget *list_item;
10303   GList *item_list;
10304   int i, l;
10305
10306   if (data->length < 0)
10307     {
10308       g_print ("Selection retrieval failed\n");
10309       return;
10310     }
10311   if (data->type != GDK_SELECTION_TYPE_ATOM)
10312     {
10313       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
10314       return;
10315     }
10316
10317   /* Clear out any current list items */
10318
10319   gtk_list_clear_items (GTK_LIST(list), 0, -1);
10320
10321   /* Add new items to list */
10322
10323   atoms = (GdkAtom *)data->data;
10324
10325   item_list = NULL;
10326   l = data->length / sizeof (GdkAtom);
10327   for (i = 0; i < l; i++)
10328     {
10329       char *name;
10330       name = gdk_atom_name (atoms[i]);
10331       if (name != NULL)
10332         {
10333           list_item = gtk_list_item_new_with_label (name);
10334           g_free (name);
10335         }
10336       else
10337         list_item = gtk_list_item_new_with_label ("(bad atom)");
10338
10339       gtk_widget_show (list_item);
10340       item_list = g_list_append (item_list, list_item);
10341     }
10342
10343   gtk_list_append_items (GTK_LIST (list), item_list);
10344
10345   return;
10346 }
10347
10348 void
10349 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
10350 {
10351   static GdkAtom targets_atom = GDK_NONE;
10352
10353   if (targets_atom == GDK_NONE)
10354     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
10355
10356   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
10357                          GDK_CURRENT_TIME);
10358 }
10359
10360 void
10361 create_selection_test (void)
10362 {
10363   static GtkWidget *window = NULL;
10364   GtkWidget *button;
10365   GtkWidget *vbox;
10366   GtkWidget *scrolled_win;
10367   GtkWidget *list;
10368   GtkWidget *label;
10369
10370   if (!window)
10371     {
10372       window = gtk_dialog_new ();
10373
10374       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10375                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
10376                           &window);
10377
10378       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
10379       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10380
10381       /* Create the list */
10382
10383       vbox = gtk_vbox_new (FALSE, 5);
10384       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
10385       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
10386                           TRUE, TRUE, 0);
10387
10388       label = gtk_label_new ("Gets available targets for current selection");
10389       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
10390
10391       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
10392       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
10393                                       GTK_POLICY_AUTOMATIC, 
10394                                       GTK_POLICY_AUTOMATIC);
10395       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
10396       gtk_widget_set_usize (scrolled_win, 100, 200);
10397
10398       list = gtk_list_new ();
10399       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
10400
10401       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
10402                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
10403
10404       /* .. And create some buttons */
10405       button = gtk_button_new_with_label ("Get Targets");
10406       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
10407                           button, TRUE, TRUE, 0);
10408
10409       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10410                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
10411
10412       button = gtk_button_new_with_label ("Quit");
10413       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
10414                           button, TRUE, TRUE, 0);
10415
10416       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10417                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
10418                                  GTK_OBJECT (window));
10419     }
10420
10421   if (!GTK_WIDGET_VISIBLE (window))
10422     gtk_widget_show_all (window);
10423   else
10424     gtk_widget_destroy (window);
10425 }
10426
10427 /*
10428  * Gamma Curve
10429  */
10430
10431 void
10432 create_gamma_curve (void)
10433 {
10434   static GtkWidget *window = NULL, *curve;
10435   static int count = 0;
10436   gfloat vec[256];
10437   gint max;
10438   gint i;
10439
10440   if (!window)
10441     {
10442       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10443       gtk_window_set_title (GTK_WINDOW (window), "test");
10444       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10445
10446       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10447                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
10448                           &window);
10449
10450       curve = gtk_gamma_curve_new ();
10451       gtk_container_add (GTK_CONTAINER (window), curve);
10452       gtk_widget_show (curve);
10453     }
10454
10455   max = 127 + (count % 2)*128;
10456   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
10457                        0, max, 0, max);
10458   for (i = 0; i < max; ++i)
10459     vec[i] = (127 / sqrt (max)) * sqrt (i);
10460   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
10461                         max, vec);
10462
10463   if (!GTK_WIDGET_VISIBLE (window))
10464     gtk_widget_show (window);
10465   else if (count % 4 == 3)
10466     {
10467       gtk_widget_destroy (window);
10468       window = NULL;
10469     }
10470
10471   ++count;
10472 }
10473
10474 /*
10475  * Test scrolling
10476  */
10477
10478 static int scroll_test_pos = 0.0;
10479
10480 static gint
10481 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
10482                     GtkAdjustment *adj)
10483 {
10484   gint i,j;
10485   gint imin, imax, jmin, jmax;
10486   
10487   imin = (event->area.x) / 10;
10488   imax = (event->area.x + event->area.width + 9) / 10;
10489
10490   jmin = ((int)adj->value + event->area.y) / 10;
10491   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
10492
10493   gdk_window_clear_area (widget->window,
10494                          event->area.x, event->area.y,
10495                          event->area.width, event->area.height);
10496
10497   for (i=imin; i<imax; i++)
10498     for (j=jmin; j<jmax; j++)
10499       if ((i+j) % 2)
10500         gdk_draw_rectangle (widget->window, 
10501                             widget->style->black_gc,
10502                             TRUE,
10503                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
10504
10505   return TRUE;
10506 }
10507
10508 static gint
10509 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
10510                     GtkAdjustment *adj)
10511 {
10512   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
10513                                     -adj->page_increment / 2:
10514                                     adj->page_increment / 2);
10515   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
10516   gtk_adjustment_set_value (adj, new_value);  
10517   
10518   return TRUE;
10519 }
10520
10521 static void
10522 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
10523                        GtkAdjustment *adj)
10524 {
10525   adj->page_increment = 0.9 * widget->allocation.height;
10526   adj->page_size = widget->allocation.height;
10527
10528   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
10529 }
10530
10531 static void
10532 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
10533 {
10534   /* gint source_min = (int)adj->value - scroll_test_pos; */
10535   gint dy;
10536
10537   dy = scroll_test_pos - (int)adj->value;
10538   scroll_test_pos = adj->value;
10539
10540   if (!GTK_WIDGET_DRAWABLE (widget))
10541     return;
10542   gdk_window_scroll (widget->window, 0, dy);
10543   gdk_window_process_updates (widget->window, FALSE);
10544 }
10545
10546
10547 void
10548 create_scroll_test (void)
10549 {
10550   static GtkWidget *window = NULL;
10551   GtkWidget *hbox;
10552   GtkWidget *drawing_area;
10553   GtkWidget *scrollbar;
10554   GtkWidget *button;
10555   GtkAdjustment *adj;
10556   GdkGeometry geometry;
10557   GdkWindowHints geometry_mask;
10558   
10559   if (!window)
10560     {
10561       window = gtk_dialog_new ();
10562
10563       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10564                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
10565                           &window);
10566
10567       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
10568       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10569
10570       hbox = gtk_hbox_new (FALSE, 0);
10571       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
10572                           TRUE, TRUE, 0);
10573       gtk_widget_show (hbox);
10574
10575       drawing_area = gtk_drawing_area_new ();
10576       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
10577       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
10578       gtk_widget_show (drawing_area);
10579
10580       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
10581
10582       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
10583       scroll_test_pos = 0.0;
10584
10585       scrollbar = gtk_vscrollbar_new (adj);
10586       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
10587       gtk_widget_show (scrollbar);
10588
10589       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
10590                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
10591       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
10592                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
10593       gtk_signal_connect (GTK_OBJECT (drawing_area), "scroll_event",
10594                           GTK_SIGNAL_FUNC (scroll_test_scroll), adj);
10595       
10596       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10597                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
10598                           drawing_area);
10599       
10600       /* .. And create some buttons */
10601
10602       button = gtk_button_new_with_label ("Quit");
10603       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
10604                           button, TRUE, TRUE, 0);
10605
10606       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10607                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
10608                                  GTK_OBJECT (window));
10609       gtk_widget_show (button);
10610
10611       /* Set up gridded geometry */
10612
10613       geometry_mask = GDK_HINT_MIN_SIZE | 
10614                        GDK_HINT_BASE_SIZE | 
10615                        GDK_HINT_RESIZE_INC;
10616
10617       geometry.min_width = 20;
10618       geometry.min_height = 20;
10619       geometry.base_width = 0;
10620       geometry.base_height = 0;
10621       geometry.width_inc = 10;
10622       geometry.height_inc = 10;
10623       
10624       gtk_window_set_geometry_hints (GTK_WINDOW (window),
10625                                drawing_area, &geometry, geometry_mask);
10626     }
10627
10628   if (!GTK_WIDGET_VISIBLE (window))
10629     gtk_widget_show (window);
10630   else
10631     gtk_widget_destroy (window);
10632 }
10633
10634 /*
10635  * Timeout Test
10636  */
10637
10638 static int timer = 0;
10639
10640 gint
10641 timeout_test (GtkWidget *label)
10642 {
10643   static int count = 0;
10644   static char buffer[32];
10645
10646   sprintf (buffer, "count: %d", ++count);
10647   gtk_label_set_text (GTK_LABEL (label), buffer);
10648
10649   return TRUE;
10650 }
10651
10652 void
10653 start_timeout_test (GtkWidget *widget,
10654                     GtkWidget *label)
10655 {
10656   if (!timer)
10657     {
10658       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
10659     }
10660 }
10661
10662 void
10663 stop_timeout_test (GtkWidget *widget,
10664                    gpointer   data)
10665 {
10666   if (timer)
10667     {
10668       gtk_timeout_remove (timer);
10669       timer = 0;
10670     }
10671 }
10672
10673 void
10674 destroy_timeout_test (GtkWidget  *widget,
10675                       GtkWidget **window)
10676 {
10677   stop_timeout_test (NULL, NULL);
10678
10679   *window = NULL;
10680 }
10681
10682 void
10683 create_timeout_test (void)
10684 {
10685   static GtkWidget *window = NULL;
10686   GtkWidget *button;
10687   GtkWidget *label;
10688
10689   if (!window)
10690     {
10691       window = gtk_dialog_new ();
10692
10693       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10694                           GTK_SIGNAL_FUNC(destroy_timeout_test),
10695                           &window);
10696
10697       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
10698       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10699
10700       label = gtk_label_new ("count: 0");
10701       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
10702       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
10703                           label, TRUE, TRUE, 0);
10704       gtk_widget_show (label);
10705
10706       button = gtk_button_new_with_label ("close");
10707       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10708                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
10709                                  GTK_OBJECT (window));
10710       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10711       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10712                           button, TRUE, TRUE, 0);
10713       gtk_widget_grab_default (button);
10714       gtk_widget_show (button);
10715
10716       button = gtk_button_new_with_label ("start");
10717       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10718                           GTK_SIGNAL_FUNC(start_timeout_test),
10719                           label);
10720       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10721       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10722                           button, TRUE, TRUE, 0);
10723       gtk_widget_show (button);
10724
10725       button = gtk_button_new_with_label ("stop");
10726       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10727                           GTK_SIGNAL_FUNC(stop_timeout_test),
10728                           NULL);
10729       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10730       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10731                           button, TRUE, TRUE, 0);
10732       gtk_widget_show (button);
10733     }
10734
10735   if (!GTK_WIDGET_VISIBLE (window))
10736     gtk_widget_show (window);
10737   else
10738     gtk_widget_destroy (window);
10739 }
10740
10741 /*
10742  * Idle Test
10743  */
10744
10745 static int idle_id = 0;
10746
10747 static gint
10748 idle_test (GtkWidget *label)
10749 {
10750   static int count = 0;
10751   static char buffer[32];
10752
10753   sprintf (buffer, "count: %d", ++count);
10754   gtk_label_set_text (GTK_LABEL (label), buffer);
10755
10756   return TRUE;
10757 }
10758
10759 static void
10760 start_idle_test (GtkWidget *widget,
10761                  GtkWidget *label)
10762 {
10763   if (!idle_id)
10764     {
10765       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
10766     }
10767 }
10768
10769 static void
10770 stop_idle_test (GtkWidget *widget,
10771                 gpointer   data)
10772 {
10773   if (idle_id)
10774     {
10775       gtk_idle_remove (idle_id);
10776       idle_id = 0;
10777     }
10778 }
10779
10780 static void
10781 destroy_idle_test (GtkWidget  *widget,
10782                    GtkWidget **window)
10783 {
10784   stop_idle_test (NULL, NULL);
10785
10786   *window = NULL;
10787 }
10788
10789 static void
10790 toggle_idle_container (GtkObject *button,
10791                        GtkContainer *container)
10792 {
10793   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (gtk_object_get_user_data (button)));
10794 }
10795
10796 static void
10797 create_idle_test (void)
10798 {
10799   static GtkWidget *window = NULL;
10800   GtkWidget *button;
10801   GtkWidget *label;
10802   GtkWidget *container;
10803
10804   if (!window)
10805     {
10806       GtkWidget *button2;
10807       GtkWidget *frame;
10808       GtkWidget *box;
10809
10810       window = gtk_dialog_new ();
10811
10812       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10813                           GTK_SIGNAL_FUNC(destroy_idle_test),
10814                           &window);
10815
10816       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
10817       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10818
10819       label = gtk_label_new ("count: 0");
10820       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
10821       gtk_widget_show (label);
10822       
10823       container =
10824         gtk_widget_new (GTK_TYPE_HBOX,
10825                         "visible", TRUE,
10826                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
10827                          * "GtkWidget::visible", TRUE,
10828                          */
10829                          "child", label,
10830                         /* NULL), */
10831                         NULL);
10832       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
10833                           container, TRUE, TRUE, 0);
10834
10835       frame =
10836         gtk_widget_new (GTK_TYPE_FRAME,
10837                         "border_width", 5,
10838                         "label", "Label Container",
10839                         "visible", TRUE,
10840                         "parent", GTK_DIALOG (window)->vbox,
10841                         NULL);
10842       box =
10843         gtk_widget_new (GTK_TYPE_VBOX,
10844                         "visible", TRUE,
10845                         "parent", frame,
10846                         NULL);
10847       button =
10848         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
10849                                           "label", "Resize-Parent",
10850                                           "user_data", (void*)GTK_RESIZE_PARENT,
10851                                           "visible", TRUE,
10852                                           "parent", box,
10853                                           NULL),
10854                           "signal::clicked", toggle_idle_container, container,
10855                           NULL);
10856       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
10857                                "label", "Resize-Queue",
10858                                "user_data", (void*)GTK_RESIZE_QUEUE,
10859                                "group", button,
10860                                "visible", TRUE,
10861                                "parent", box,
10862                                NULL);
10863       g_object_connect (button,
10864                         "signal::clicked", toggle_idle_container, container,
10865                         NULL);
10866       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
10867                                 "label", "Resize-Immediate",
10868                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
10869                                 NULL);
10870       g_object_connect (button2,
10871                         "signal::clicked", toggle_idle_container, container,
10872                         NULL);
10873       g_object_set (button2,
10874                     "group", button,
10875                     "visible", TRUE,
10876                     "parent", box,
10877                     NULL);
10878
10879       button = gtk_button_new_with_label ("close");
10880       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10881                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
10882                                  GTK_OBJECT (window));
10883       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10884       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10885                           button, TRUE, TRUE, 0);
10886       gtk_widget_grab_default (button);
10887       gtk_widget_show (button);
10888
10889       button = gtk_button_new_with_label ("start");
10890       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10891                           GTK_SIGNAL_FUNC(start_idle_test),
10892                           label);
10893       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10894       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10895                           button, TRUE, TRUE, 0);
10896       gtk_widget_show (button);
10897
10898       button = gtk_button_new_with_label ("stop");
10899       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10900                           GTK_SIGNAL_FUNC(stop_idle_test),
10901                           NULL);
10902       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10903       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10904                           button, TRUE, TRUE, 0);
10905       gtk_widget_show (button);
10906     }
10907
10908   if (!GTK_WIDGET_VISIBLE (window))
10909     gtk_widget_show (window);
10910   else
10911     gtk_widget_destroy (window);
10912 }
10913
10914 /*
10915  * rc file test
10916  */
10917
10918 void
10919 reload_all_rc_files (void)
10920 {
10921   static GdkAtom atom_rcfiles = GDK_NONE;
10922
10923   GdkEventClient sev;
10924   int i;
10925   
10926   if (!atom_rcfiles)
10927     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
10928
10929   for(i = 0; i < 5; i++)
10930     sev.data.l[i] = 0;
10931   sev.data_format = 32;
10932   sev.message_type = atom_rcfiles;
10933   gdk_event_send_clientmessage_toall ((GdkEvent *) &sev);
10934 }
10935
10936 void
10937 create_rc_file (void)
10938 {
10939   static GtkWidget *window = NULL;
10940   GtkWidget *button;
10941   GtkWidget *frame;
10942   GtkWidget *vbox;
10943   GtkWidget *label;
10944
10945   if (!window)
10946     {
10947       window = gtk_dialog_new ();
10948
10949       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10950                           GTK_SIGNAL_FUNC(destroy_idle_test),
10951                           &window);
10952
10953       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
10954       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
10955
10956       vbox = gtk_vbox_new (FALSE, 0);
10957       gtk_container_add (GTK_CONTAINER (frame), vbox);
10958       
10959       label = gtk_label_new ("This label should be red");
10960       gtk_widget_set_name (label, "testgtk-red-label");
10961       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
10962
10963       label = gtk_label_new ("This label should be green");
10964       gtk_widget_set_name (label, "testgtk-green-label");
10965       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
10966
10967       label = gtk_label_new ("This label should be blue");
10968       gtk_widget_set_name (label, "testgtk-blue-label");
10969       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
10970
10971       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
10972       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
10973
10974       button = gtk_button_new_with_label ("Reload");
10975       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10976                           GTK_SIGNAL_FUNC(gtk_rc_reparse_all), NULL);
10977       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10978       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10979                           button, TRUE, TRUE, 0);
10980       gtk_widget_grab_default (button);
10981
10982       button = gtk_button_new_with_label ("Reload All");
10983       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10984                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
10985       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10986       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10987                           button, TRUE, TRUE, 0);
10988
10989       button = gtk_button_new_with_label ("Close");
10990       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10991                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
10992                                  GTK_OBJECT (window));
10993       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10994       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
10995                           button, TRUE, TRUE, 0);
10996     }
10997
10998   if (!GTK_WIDGET_VISIBLE (window))
10999     gtk_widget_show_all (window);
11000   else
11001     gtk_widget_destroy (window);
11002 }
11003
11004 /*
11005  * Test of recursive mainloop
11006  */
11007
11008 void
11009 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
11010 {
11011   *window = NULL;
11012   gtk_main_quit ();
11013 }
11014
11015 void
11016 create_mainloop (void)
11017 {
11018   static GtkWidget *window = NULL;
11019   GtkWidget *label;
11020   GtkWidget *button;
11021
11022   if (!window)
11023     {
11024       window = gtk_dialog_new ();
11025
11026       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
11027
11028       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11029                           GTK_SIGNAL_FUNC(mainloop_destroyed),
11030                           &window);
11031
11032       label = gtk_label_new ("In recursive main loop...");
11033       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
11034
11035       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
11036                           TRUE, TRUE, 0);
11037       gtk_widget_show (label);
11038
11039       button = gtk_button_new_with_label ("Leave");
11040       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
11041                           FALSE, TRUE, 0);
11042
11043       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11044                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11045                                  GTK_OBJECT (window));
11046
11047       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11048       gtk_widget_grab_default (button);
11049
11050       gtk_widget_show (button);
11051     }
11052
11053   if (!GTK_WIDGET_VISIBLE (window))
11054     {
11055       gtk_widget_show (window);
11056
11057       g_print ("create_mainloop: start\n");
11058       gtk_main ();
11059       g_print ("create_mainloop: done\n");
11060     }
11061   else
11062     gtk_widget_destroy (window);
11063 }
11064
11065 gboolean
11066 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
11067 {
11068   GtkLayout *layout;
11069
11070   gint i,j;
11071   gint imin, imax, jmin, jmax;
11072
11073   layout = GTK_LAYOUT (widget);
11074
11075   if (event->window != layout->bin_window)
11076     return FALSE;
11077   
11078   imin = (event->area.x) / 10;
11079   imax = (event->area.x + event->area.width + 9) / 10;
11080
11081   jmin = (event->area.y) / 10;
11082   jmax = (event->area.y + event->area.height + 9) / 10;
11083
11084   for (i=imin; i<imax; i++)
11085     for (j=jmin; j<jmax; j++)
11086       if ((i+j) % 2)
11087         gdk_draw_rectangle (layout->bin_window,
11088                             widget->style->black_gc,
11089                             TRUE,
11090                             10*i, 10*j, 
11091                             1+i%10, 1+j%10);
11092   
11093   return FALSE;
11094 }
11095
11096 void create_layout (void)
11097 {
11098   static GtkWidget *window = NULL;
11099   GtkWidget *layout;
11100   GtkWidget *scrolledwindow;
11101   GtkWidget *button;
11102
11103   if (!window)
11104     {
11105       gchar buf[16];
11106
11107       gint i, j;
11108       
11109       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11110       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11111                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11112                           &window);
11113
11114       gtk_window_set_title (GTK_WINDOW (window), "Layout");
11115       gtk_widget_set_usize (window, 200, 200);
11116
11117       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
11118       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
11119                                            GTK_SHADOW_IN);
11120       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
11121                                          GTK_CORNER_TOP_RIGHT);
11122
11123       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
11124       
11125       layout = gtk_layout_new (NULL, NULL);
11126       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
11127
11128       /* We set step sizes here since GtkLayout does not set
11129        * them itself.
11130        */
11131       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
11132       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
11133       
11134       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
11135       gtk_signal_connect (GTK_OBJECT (layout), "expose_event",
11136                           GTK_SIGNAL_FUNC (layout_expose_handler), NULL);
11137       
11138       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
11139       
11140       for (i=0 ; i < 16 ; i++)
11141         for (j=0 ; j < 16 ; j++)
11142           {
11143             sprintf(buf, "Button %d, %d", i, j);
11144             if ((i + j) % 2)
11145               button = gtk_button_new_with_label (buf);
11146             else
11147               button = gtk_label_new (buf);
11148
11149             gtk_layout_put (GTK_LAYOUT (layout), button,
11150                             j*100, i*100);
11151           }
11152
11153       for (i=16; i < 1280; i++)
11154         {
11155           sprintf(buf, "Button %d, %d", i, 0);
11156           if (i % 2)
11157             button = gtk_button_new_with_label (buf);
11158           else
11159             button = gtk_label_new (buf);
11160
11161           gtk_layout_put (GTK_LAYOUT (layout), button,
11162                           0, i*100);
11163         }
11164     }
11165
11166   if (!GTK_WIDGET_VISIBLE (window))
11167     gtk_widget_show_all (window);
11168   else
11169     gtk_widget_destroy (window);
11170 }
11171
11172 void
11173 create_styles (void)
11174 {
11175   static GtkWidget *window = NULL;
11176   GtkWidget *label;
11177   GtkWidget *button;
11178   GtkWidget *entry;
11179   GtkWidget *vbox;
11180   static GdkColor red =    { 0, 0xffff, 0,      0      };
11181   static GdkColor green =  { 0, 0,      0xffff, 0      };
11182   static GdkColor blue =   { 0, 0,      0,      0xffff };
11183   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
11184   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
11185   PangoFontDescription *font_desc;
11186
11187   GtkRcStyle *rc_style;
11188
11189   if (!window)
11190     {
11191       window = gtk_dialog_new ();
11192       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11193                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11194                           &window);
11195
11196       
11197       button = gtk_button_new_with_label ("Close");
11198       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11199                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11200                                  GTK_OBJECT (window));
11201       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11202       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11203                           button, TRUE, TRUE, 0);
11204       gtk_widget_show (button);
11205
11206       vbox = gtk_vbox_new (FALSE, 5);
11207       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11208       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
11209       
11210       label = gtk_label_new ("Font:");
11211       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11212       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11213
11214       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
11215
11216       button = gtk_button_new_with_label ("Some Text");
11217       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
11218       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11219
11220       label = gtk_label_new ("Foreground:");
11221       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11222       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11223
11224       button = gtk_button_new_with_label ("Some Text");
11225       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
11226       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11227
11228       label = gtk_label_new ("Background:");
11229       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11230       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11231
11232       button = gtk_button_new_with_label ("Some Text");
11233       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
11234       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11235
11236       label = gtk_label_new ("Text:");
11237       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11238       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11239
11240       entry = gtk_entry_new ();
11241       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11242       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
11243       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11244
11245       label = gtk_label_new ("Base:");
11246       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11247       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11248
11249       entry = gtk_entry_new ();
11250       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11251       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
11252       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11253
11254       label = gtk_label_new ("Multiple:");
11255       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11256       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11257
11258       button = gtk_button_new_with_label ("Some Text");
11259
11260       rc_style = gtk_rc_style_new ();
11261
11262       rc_style->font_desc = pango_font_description_copy (font_desc);
11263       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
11264       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
11265       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
11266       rc_style->fg[GTK_STATE_NORMAL] = yellow;
11267       rc_style->bg[GTK_STATE_NORMAL] = blue;
11268       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
11269       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
11270       rc_style->fg[GTK_STATE_ACTIVE] = red;
11271       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
11272       rc_style->xthickness = 5;
11273       rc_style->ythickness = 5;
11274
11275       gtk_widget_modify_style (button, rc_style);
11276       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
11277
11278       g_object_unref (G_OBJECT (rc_style));
11279       
11280       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11281     }
11282   
11283   if (!GTK_WIDGET_VISIBLE (window))
11284     gtk_widget_show_all (window);
11285   else
11286     gtk_widget_destroy (window);
11287 }
11288
11289 /*
11290  * Main Window and Exit
11291  */
11292
11293 void
11294 do_exit (GtkWidget *widget, GtkWidget *window)
11295 {
11296   gtk_widget_destroy (window);
11297   gtk_main_quit ();
11298 }
11299
11300 struct {
11301   char *label;
11302   void (*func) ();
11303   gboolean do_not_benchmark;
11304 } buttons[] =
11305 {
11306   { "big windows", create_big_windows },
11307   { "button box", create_button_box },
11308   { "buttons", create_buttons },
11309   { "check buttons", create_check_buttons },
11310   { "clist", create_clist},
11311   { "color selection", create_color_selection },
11312   { "ctree", create_ctree },
11313   { "cursors", create_cursors },
11314   { "dialog", create_dialog },
11315   { "entry", create_entry },
11316   { "event watcher", create_event_watcher },
11317   { "file selection", create_file_selection },
11318   { "flipping", create_flipping },
11319   { "focus", create_focus },
11320   { "font selection", create_font_selection },
11321   { "gamma curve", create_gamma_curve, TRUE },
11322   { "handle box", create_handle_box },
11323   { "image from drawable", create_get_image },
11324   { "image", create_image },
11325   { "item factory", create_item_factory },
11326   { "labels", create_labels },
11327   { "layout", create_layout },
11328   { "list", create_list },
11329   { "menus", create_menus },
11330   { "message dialog", create_message_dialog },
11331   { "modal window", create_modal_window, TRUE },
11332   { "notebook", create_notebook },
11333   { "panes", create_panes },
11334   { "paned keyboard", create_paned_keyboard_navigation },
11335   { "pixmap", create_pixmap },
11336   { "preview color", create_color_preview, TRUE },
11337   { "preview gray", create_gray_preview, TRUE },
11338   { "progress bar", create_progress_bar },
11339   { "properties", create_properties },
11340   { "radio buttons", create_radio_buttons },
11341   { "range controls", create_range_controls },
11342   { "rc file", create_rc_file },
11343   { "reparent", create_reparent },
11344   { "rulers", create_rulers },
11345   { "saved position", create_saved_position },
11346   { "scrolled windows", create_scrolled_windows },
11347   { "shapes", create_shapes },
11348   { "size groups", create_size_groups },
11349   { "spinbutton", create_spins },
11350   { "statusbar", create_statusbar },
11351   { "styles", create_styles },
11352   { "test idle", create_idle_test },
11353   { "test mainloop", create_mainloop, TRUE },
11354   { "test scrolling", create_scroll_test },
11355   { "test selection", create_selection_test },
11356   { "test timeout", create_timeout_test },
11357   { "text", create_text },
11358   { "toggle buttons", create_toggle_buttons },
11359   { "toolbar", create_toolbar },
11360   { "tooltips", create_tooltips },
11361   { "tree", create_tree_mode_window},
11362   { "WM hints", create_wmhints },
11363   { "window sizing", create_window_sizing },
11364   { "window states", create_window_states }
11365 };
11366 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
11367
11368 void
11369 create_main_window (void)
11370 {
11371   GtkWidget *window;
11372   GtkWidget *box1;
11373   GtkWidget *box2;
11374   GtkWidget *scrolled_window;
11375   GtkWidget *button;
11376   GtkWidget *label;
11377   gchar buffer[64];
11378   GtkWidget *separator;
11379   GdkGeometry geometry;
11380   int i;
11381
11382   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11383   gtk_widget_set_name (window, "main window");
11384   gtk_widget_set_uposition (window, 20, 20);
11385   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
11386
11387   geometry.min_width = -1;
11388   geometry.min_height = -1;
11389   geometry.max_width = -1;
11390   geometry.max_height = G_MAXSHORT;
11391   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
11392                                  &geometry,
11393                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
11394
11395   gtk_signal_connect (GTK_OBJECT (window), "destroy",
11396                       GTK_SIGNAL_FUNC(gtk_main_quit),
11397                       NULL);
11398   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
11399                       GTK_SIGNAL_FUNC (gtk_false),
11400                       NULL);
11401
11402   box1 = gtk_vbox_new (FALSE, 0);
11403   gtk_container_add (GTK_CONTAINER (window), box1);
11404
11405   if (gtk_micro_version > 0)
11406     sprintf (buffer,
11407              "Gtk+ v%d.%d.%d",
11408              gtk_major_version,
11409              gtk_minor_version,
11410              gtk_micro_version);
11411   else
11412     sprintf (buffer,
11413              "Gtk+ v%d.%d",
11414              gtk_major_version,
11415              gtk_minor_version);
11416
11417   label = gtk_label_new (buffer);
11418   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
11419   gtk_widget_set_name (label, "testgtk-version-label");
11420
11421   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
11422   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
11423   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
11424                                   GTK_POLICY_NEVER, 
11425                                   GTK_POLICY_AUTOMATIC);
11426   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
11427
11428   box2 = gtk_vbox_new (FALSE, 0);
11429   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
11430   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
11431   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
11432                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
11433   gtk_widget_show (box2);
11434
11435   for (i = 0; i < nbuttons; i++)
11436     {
11437       button = gtk_button_new_with_label (buttons[i].label);
11438       if (buttons[i].func)
11439         gtk_signal_connect (GTK_OBJECT (button), 
11440                             "clicked", 
11441                             GTK_SIGNAL_FUNC(buttons[i].func),
11442                             NULL);
11443       else
11444         gtk_widget_set_sensitive (button, FALSE);
11445       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
11446     }
11447
11448   separator = gtk_hseparator_new ();
11449   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
11450
11451   box2 = gtk_vbox_new (FALSE, 10);
11452   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
11453   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
11454
11455   button = gtk_button_new_with_mnemonic ("_Close");
11456   gtk_signal_connect (GTK_OBJECT (button), "clicked",
11457                       GTK_SIGNAL_FUNC (do_exit),
11458                       window);
11459   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
11460   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11461   gtk_widget_grab_default (button);
11462
11463   gtk_widget_show_all (window);
11464 }
11465
11466 static void
11467 test_init ()
11468 {
11469   if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
11470     {
11471       putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
11472       putenv ("GTK_IM_MODULE_FILE=../modules/input/gtk.immodules");
11473     }
11474 }
11475
11476 static char *
11477 pad (const char *str, int to)
11478 {
11479   static char buf[256];
11480   int len = strlen (str);
11481   int i;
11482
11483   for (i = 0; i < to; i++)
11484     buf[i] = ' ';
11485
11486   buf[to] = '\0';
11487
11488   memcpy (buf, str, len);
11489
11490   return buf;
11491 }
11492
11493 static void
11494 bench_iteration (void (* fn) ())
11495 {
11496   fn (); /* on */
11497   while (g_main_iteration (FALSE));
11498   fn (); /* off */
11499   while (g_main_iteration (FALSE));
11500 }
11501
11502 void
11503 do_real_bench (void (* fn) (), char *name, int num)
11504 {
11505   GTimeVal tv0, tv1;
11506   double dt_first;
11507   double dt;
11508   int n;
11509   static gboolean printed_headers = FALSE;
11510
11511   if (!printed_headers) {
11512     g_print ("Test                 Iters      First      Other\n");
11513     g_print ("-------------------- ----- ---------- ----------\n");
11514     printed_headers = TRUE;
11515   }
11516
11517   g_get_current_time (&tv0);
11518   bench_iteration (fn); 
11519   g_get_current_time (&tv1);
11520
11521   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
11522         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
11523
11524   g_get_current_time (&tv0);
11525   for (n = 0; n < num - 1; n++)
11526     bench_iteration (fn); 
11527   g_get_current_time (&tv1);
11528   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
11529         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
11530
11531   g_print ("%s %5d ", pad (name, 20), num);
11532   if (num > 1)
11533     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
11534   else
11535     g_print ("%10.1f\n", dt_first);
11536 }
11537
11538 void
11539 do_bench (char* what, int num)
11540 {
11541   int i;
11542   void (* fn) ();
11543   fn = NULL;
11544
11545   if (g_strcasecmp (what, "ALL") == 0)
11546     {
11547       for (i = 0; i < nbuttons; i++)
11548         {
11549           if (!buttons[i].do_not_benchmark)
11550             do_real_bench (buttons[i].func, buttons[i].label, num);
11551         }
11552
11553       return;
11554     }
11555   else
11556     {
11557       for (i = 0; i < nbuttons; i++)
11558         {
11559           if (strcmp (buttons[i].label, what) == 0)
11560             {
11561               fn = buttons[i].func;
11562               break;
11563             }
11564         }
11565       
11566       if (!fn)
11567         g_print ("Can't bench: \"%s\" not found.\n", what);
11568       else
11569         do_real_bench (fn, buttons[i].label, num);
11570     }
11571 }
11572
11573 void 
11574 usage (void)
11575 {
11576   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
11577   exit (1);
11578 }
11579
11580 int
11581 main (int argc, char *argv[])
11582 {
11583   GtkBindingSet *binding_set;
11584   int i;
11585   gboolean done_benchmarks = FALSE;
11586
11587   srand (time (NULL));
11588
11589   test_init ();
11590
11591   /* Check to see if we are being run from the correct
11592    * directory.
11593    */
11594   if (file_exists ("testgtkrc"))
11595     gtk_rc_add_default_file ("testgtkrc");
11596
11597   gtk_init (&argc, &argv);
11598
11599   /*  benchmarking
11600    */
11601   for (i = 1; i < argc; i++)
11602     {
11603       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
11604         {
11605           int num = 1;
11606           char *nextarg;
11607           char *what;
11608           char *count;
11609           
11610           nextarg = strchr (argv[i], '=');
11611           if (nextarg)
11612             nextarg++;
11613           else
11614             {
11615               i++;
11616               if (i == argc)
11617                 usage ();
11618               nextarg = argv[i];
11619             }
11620
11621           count = strchr (nextarg, ':');
11622           if (count)
11623             {
11624               what = g_strndup (nextarg, count - nextarg);
11625               count++;
11626               num = atoi (count);
11627               if (num <= 0)
11628                 usage ();
11629             }
11630           else
11631             what = g_strdup (nextarg);
11632
11633           do_bench (what, num ? num : 1);
11634           done_benchmarks = TRUE;
11635         }
11636       else
11637         usage ();
11638     }
11639   if (done_benchmarks)
11640     return 0;
11641
11642   /* bindings test
11643    */
11644   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
11645   gtk_binding_entry_add_signal (binding_set,
11646                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
11647                                 "debug_msg",
11648                                 1,
11649                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
11650   
11651   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
11652    * changes
11653    */
11654
11655   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
11656                        "   fg[NORMAL] = \"#ff0000\"\n"
11657                        "   font = \"Sans 18\"\n"
11658                        "}\n"
11659                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
11660   
11661   create_main_window ();
11662
11663   gtk_main ();
11664
11665   if (1)
11666     {
11667       while (g_main_pending ())
11668         g_main_iteration (FALSE);
11669 #if 0
11670       sleep (1);
11671       while (g_main_pending ())
11672         g_main_iteration (FALSE);
11673 #endif
11674     }
11675   return 0;
11676 }