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