]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
d51756bcbb1f40d1d92a139d231a2690c61a83a5
[~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_display (gtk_widget_get_display (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 gchar *selection_mode_items[] =
5061 {
5062   "Single",
5063   "Browse",
5064   "Multiple"
5065 };
5066
5067 static const GtkSelectionMode selection_modes[] = {
5068   GTK_SELECTION_SINGLE,
5069   GTK_SELECTION_BROWSE,
5070   GTK_SELECTION_MULTIPLE
5071 };
5072
5073 static GtkWidget *list_omenu;
5074
5075 static void 
5076 list_toggle_sel_mode (GtkWidget *widget, gpointer data)
5077 {
5078   GtkList *list;
5079   gint i;
5080
5081   list = GTK_LIST (data);
5082
5083   if (!GTK_WIDGET_MAPPED (widget))
5084     return;
5085
5086   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5087
5088   gtk_list_set_selection_mode (list, selection_modes[i]);
5089 }
5090
5091 static void
5092 create_list (GtkWidget *widget)
5093 {
5094   static GtkWidget *window = NULL;
5095
5096   if (!window)
5097     {
5098       GtkWidget *cbox;
5099       GtkWidget *vbox;
5100       GtkWidget *hbox;
5101       GtkWidget *label;
5102       GtkWidget *scrolled_win;
5103       GtkWidget *list;
5104       GtkWidget *button;
5105       GtkWidget *separator;
5106       FILE *infile;
5107
5108       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5109
5110       gtk_window_set_screen (GTK_WINDOW (window),
5111                              gtk_widget_get_screen (widget));
5112
5113       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5114                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
5115                           &window);
5116
5117       gtk_window_set_title (GTK_WINDOW (window), "list");
5118       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5119
5120       vbox = gtk_vbox_new (FALSE, 0);
5121       gtk_container_add (GTK_CONTAINER (window), vbox);
5122
5123       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5124       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5125       gtk_widget_set_usize (scrolled_win, -1, 300);
5126       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5127       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5128                                       GTK_POLICY_AUTOMATIC,
5129                                       GTK_POLICY_AUTOMATIC);
5130
5131       list = gtk_list_new ();
5132       gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_EXTENDED);
5133       gtk_scrolled_window_add_with_viewport
5134         (GTK_SCROLLED_WINDOW (scrolled_win), list);
5135       gtk_container_set_focus_vadjustment
5136         (GTK_CONTAINER (list),
5137          gtk_scrolled_window_get_vadjustment
5138          (GTK_SCROLLED_WINDOW (scrolled_win)));
5139       gtk_container_set_focus_hadjustment
5140         (GTK_CONTAINER (list),
5141          gtk_scrolled_window_get_hadjustment
5142          (GTK_SCROLLED_WINDOW (scrolled_win)));
5143
5144       if ((infile = fopen("../gtk/gtkenums.h", "r")))
5145         {
5146           char buffer[256];
5147           char *pos;
5148           GtkWidget *item;
5149
5150           while (fgets (buffer, 256, infile))
5151             {
5152               if ((pos = strchr (buffer, '\n')))
5153                 *pos = 0;
5154               item = gtk_list_item_new_with_label (buffer);
5155               gtk_container_add (GTK_CONTAINER (list), item);
5156             }
5157           
5158           fclose (infile);
5159         }
5160
5161
5162       hbox = gtk_hbox_new (TRUE, 5);
5163       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5164       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5165
5166       button = gtk_button_new_with_label ("Insert Row");
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_add),
5170                           list);
5171
5172       button = gtk_button_new_with_label ("Clear List");
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_clear),
5176                           list);
5177
5178       button = gtk_button_new_with_label ("Remove Selection");
5179       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5180       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5181                           GTK_SIGNAL_FUNC (list_remove),
5182                           list);
5183
5184       cbox = gtk_hbox_new (FALSE, 0);
5185       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5186
5187       hbox = gtk_hbox_new (FALSE, 5);
5188       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5189       gtk_box_pack_start (GTK_BOX (cbox), hbox, TRUE, FALSE, 0);
5190
5191       label = gtk_label_new ("Selection Mode :");
5192       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5193
5194       list_omenu = build_option_menu (selection_mode_items, 3, 3, 
5195                                       list_toggle_sel_mode,
5196                                       list);
5197       gtk_box_pack_start (GTK_BOX (hbox), list_omenu, FALSE, TRUE, 0);
5198
5199       separator = gtk_hseparator_new ();
5200       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5201
5202       cbox = gtk_hbox_new (FALSE, 0);
5203       gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, TRUE, 0);
5204
5205       button = gtk_button_new_with_label ("close");
5206       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5207       gtk_box_pack_start (GTK_BOX (cbox), button, TRUE, TRUE, 0);
5208       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5209                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5210                                  GTK_OBJECT (window));
5211
5212       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5213       gtk_widget_grab_default (button);
5214     }
5215
5216   if (!GTK_WIDGET_VISIBLE (window))
5217     gtk_widget_show_all (window);
5218   else
5219     gtk_widget_destroy (window);
5220 }
5221
5222 /*
5223  * GtkCList
5224  */
5225
5226 static char * book_open_xpm[] = {
5227 "16 16 4 1",
5228 "       c None s None",
5229 ".      c black",
5230 "X      c #808080",
5231 "o      c white",
5232 "                ",
5233 "  ..            ",
5234 " .Xo.    ...    ",
5235 " .Xoo. ..oo.    ",
5236 " .Xooo.Xooo...  ",
5237 " .Xooo.oooo.X.  ",
5238 " .Xooo.Xooo.X.  ",
5239 " .Xooo.oooo.X.  ",
5240 " .Xooo.Xooo.X.  ",
5241 " .Xooo.oooo.X.  ",
5242 "  .Xoo.Xoo..X.  ",
5243 "   .Xo.o..ooX.  ",
5244 "    .X..XXXXX.  ",
5245 "    ..X.......  ",
5246 "     ..         ",
5247 "                "};
5248
5249 static char * book_closed_xpm[] = {
5250 "16 16 6 1",
5251 "       c None s None",
5252 ".      c black",
5253 "X      c red",
5254 "o      c yellow",
5255 "O      c #808080",
5256 "#      c white",
5257 "                ",
5258 "       ..       ",
5259 "     ..XX.      ",
5260 "   ..XXXXX.     ",
5261 " ..XXXXXXXX.    ",
5262 ".ooXXXXXXXXX.   ",
5263 "..ooXXXXXXXXX.  ",
5264 ".X.ooXXXXXXXXX. ",
5265 ".XX.ooXXXXXX..  ",
5266 " .XX.ooXXX..#O  ",
5267 "  .XX.oo..##OO. ",
5268 "   .XX..##OO..  ",
5269 "    .X.#OO..    ",
5270 "     ..O..      ",
5271 "      ..        ",
5272 "                "};
5273
5274 static char * mini_page_xpm[] = {
5275 "16 16 4 1",
5276 "       c None s None",
5277 ".      c black",
5278 "X      c white",
5279 "o      c #808080",
5280 "                ",
5281 "   .......      ",
5282 "   .XXXXX..     ",
5283 "   .XoooX.X.    ",
5284 "   .XXXXX....   ",
5285 "   .XooooXoo.o  ",
5286 "   .XXXXXXXX.o  ",
5287 "   .XooooooX.o  ",
5288 "   .XXXXXXXX.o  ",
5289 "   .XooooooX.o  ",
5290 "   .XXXXXXXX.o  ",
5291 "   .XooooooX.o  ",
5292 "   .XXXXXXXX.o  ",
5293 "   ..........o  ",
5294 "    oooooooooo  ",
5295 "                "};
5296
5297 static char * gtk_mini_xpm[] = {
5298 "15 20 17 1",
5299 "       c None",
5300 ".      c #14121F",
5301 "+      c #278828",
5302 "@      c #9B3334",
5303 "#      c #284C72",
5304 "$      c #24692A",
5305 "%      c #69282E",
5306 "&      c #37C539",
5307 "*      c #1D2F4D",
5308 "=      c #6D7076",
5309 "-      c #7D8482",
5310 ";      c #E24A49",
5311 ">      c #515357",
5312 ",      c #9B9C9B",
5313 "'      c #2FA232",
5314 ")      c #3CE23D",
5315 "!      c #3B6CCB",
5316 "               ",
5317 "      ***>     ",
5318 "    >.*!!!*    ",
5319 "   ***....#*=  ",
5320 "  *!*.!!!**!!# ",
5321 " .!!#*!#*!!!!# ",
5322 " @%#!.##.*!!$& ",
5323 " @;%*!*.#!#')) ",
5324 " @;;@%!!*$&)'' ",
5325 " @%.%@%$'&)$+' ",
5326 " @;...@$'*'*)+ ",
5327 " @;%..@$+*.')$ ",
5328 " @;%%;;$+..$)# ",
5329 " @;%%;@$$$'.$# ",
5330 " %;@@;;$$+))&* ",
5331 "  %;;;@+$&)&*  ",
5332 "   %;;@'))+>   ",
5333 "    %;@'&#     ",
5334 "     >%$$      ",
5335 "      >=       "};
5336
5337 #define TESTGTK_CLIST_COLUMNS 12
5338 static gint clist_rows = 0;
5339 static GtkWidget *clist_omenu;
5340
5341 static void
5342 add1000_clist (GtkWidget *widget, gpointer data)
5343 {
5344   gint i, row;
5345   char text[TESTGTK_CLIST_COLUMNS][50];
5346   char *texts[TESTGTK_CLIST_COLUMNS];
5347   GdkBitmap *mask;
5348   GdkPixmap *pixmap;
5349   GtkCList  *clist;
5350
5351   clist = GTK_CLIST (data);
5352
5353   pixmap = gdk_pixmap_create_from_xpm_d (clist->clist_window,
5354                                          &mask, 
5355                                          &GTK_WIDGET (data)->style->white,
5356                                          gtk_mini_xpm);
5357
5358   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5359     {
5360       texts[i] = text[i];
5361       sprintf (text[i], "Column %d", i);
5362     }
5363   
5364   texts[3] = NULL;
5365   sprintf (text[1], "Right");
5366   sprintf (text[2], "Center");
5367   
5368   gtk_clist_freeze (GTK_CLIST (data));
5369   for (i = 0; i < 1000; i++)
5370     {
5371       sprintf (text[0], "CListRow %d", rand() % 10000);
5372       row = gtk_clist_append (clist, texts);
5373       gtk_clist_set_pixtext (clist, row, 3, "gtk+", 5, pixmap, mask);
5374     }
5375
5376   gtk_clist_thaw (GTK_CLIST (data));
5377
5378   gdk_pixmap_unref (pixmap);
5379   gdk_bitmap_unref (mask);
5380 }
5381
5382 static void
5383 add10000_clist (GtkWidget *widget, gpointer data)
5384 {
5385   gint i;
5386   char text[TESTGTK_CLIST_COLUMNS][50];
5387   char *texts[TESTGTK_CLIST_COLUMNS];
5388
5389   for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5390     {
5391       texts[i] = text[i];
5392       sprintf (text[i], "Column %d", i);
5393     }
5394   
5395   sprintf (text[1], "Right");
5396   sprintf (text[2], "Center");
5397   
5398   gtk_clist_freeze (GTK_CLIST (data));
5399   for (i = 0; i < 10000; i++)
5400     {
5401       sprintf (text[0], "CListRow %d", rand() % 10000);
5402       gtk_clist_append (GTK_CLIST (data), texts);
5403     }
5404   gtk_clist_thaw (GTK_CLIST (data));
5405 }
5406
5407 void
5408 clear_clist (GtkWidget *widget, gpointer data)
5409 {
5410   gtk_clist_clear (GTK_CLIST (data));
5411   clist_rows = 0;
5412 }
5413
5414 void clist_remove_selection (GtkWidget *widget, GtkCList *clist)
5415 {
5416   gtk_clist_freeze (clist);
5417
5418   while (clist->selection)
5419     {
5420       gint row;
5421
5422       clist_rows--;
5423       row = GPOINTER_TO_INT (clist->selection->data);
5424
5425       gtk_clist_remove (clist, row);
5426
5427       if (clist->selection_mode == GTK_SELECTION_BROWSE)
5428         break;
5429     }
5430
5431   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
5432       clist->focus_row >= 0)
5433     gtk_clist_select_row (clist, clist->focus_row, -1);
5434
5435   gtk_clist_thaw (clist);
5436 }
5437
5438 void toggle_title_buttons (GtkWidget *widget, GtkCList *clist)
5439 {
5440   if (GTK_TOGGLE_BUTTON (widget)->active)
5441     gtk_clist_column_titles_show (clist);
5442   else
5443     gtk_clist_column_titles_hide (clist);
5444 }
5445
5446 void toggle_reorderable (GtkWidget *widget, GtkCList *clist)
5447 {
5448   gtk_clist_set_reorderable (clist, GTK_TOGGLE_BUTTON (widget)->active);
5449 }
5450
5451 static void
5452 insert_row_clist (GtkWidget *widget, gpointer data)
5453 {
5454   static char *text[] =
5455   {
5456     "This", "is an", "inserted", "row.",
5457     "This", "is an", "inserted", "row.",
5458     "This", "is an", "inserted", "row."
5459   };
5460
5461   static GtkStyle *style1 = NULL;
5462   static GtkStyle *style2 = NULL;
5463   static GtkStyle *style3 = NULL;
5464   gint row;
5465   
5466   if (GTK_CLIST (data)->focus_row >= 0)
5467     row = gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row,
5468                             text);
5469   else
5470     row = gtk_clist_prepend (GTK_CLIST (data), text);
5471
5472   if (!style1)
5473     {
5474       GdkColor col1;
5475       GdkColor col2;
5476
5477       col1.red   = 0;
5478       col1.green = 56000;
5479       col1.blue  = 0;
5480       col2.red   = 32000;
5481       col2.green = 0;
5482       col2.blue  = 56000;
5483
5484       style1 = gtk_style_copy (GTK_WIDGET (data)->style);
5485       style1->base[GTK_STATE_NORMAL] = col1;
5486       style1->base[GTK_STATE_SELECTED] = col2;
5487
5488       style2 = gtk_style_copy (GTK_WIDGET (data)->style);
5489       style2->fg[GTK_STATE_NORMAL] = col1;
5490       style2->fg[GTK_STATE_SELECTED] = col2;
5491
5492       style3 = gtk_style_copy (GTK_WIDGET (data)->style);
5493       style3->fg[GTK_STATE_NORMAL] = col1;
5494       style3->base[GTK_STATE_NORMAL] = col2;
5495       pango_font_description_free (style3->font_desc);
5496       style3->font_desc = pango_font_description_from_string ("courier 12");
5497     }
5498
5499   gtk_clist_set_cell_style (GTK_CLIST (data), row, 3, style1);
5500   gtk_clist_set_cell_style (GTK_CLIST (data), row, 4, style2);
5501   gtk_clist_set_cell_style (GTK_CLIST (data), row, 0, style3);
5502
5503   clist_rows++;
5504 }
5505
5506 static void
5507 clist_warning_test (GtkWidget *button,
5508                     GtkWidget *clist)
5509 {
5510   GtkWidget *child;
5511   static gboolean add_remove = FALSE;
5512
5513   add_remove = !add_remove;
5514
5515   child = gtk_label_new ("Test");
5516   gtk_widget_ref (child);
5517   gtk_object_sink (GTK_OBJECT (child));
5518
5519   if (add_remove)
5520     gtk_container_add (GTK_CONTAINER (clist), child);
5521   else
5522     {
5523       child->parent = clist;
5524       gtk_container_remove (GTK_CONTAINER (clist), child);
5525       child->parent = NULL;
5526     }
5527
5528   gtk_widget_destroy (child);
5529   gtk_widget_unref (child);
5530 }
5531
5532 static void
5533 undo_selection (GtkWidget *button, GtkCList *clist)
5534 {
5535   gtk_clist_undo_selection (clist);
5536 }
5537
5538 static void 
5539 clist_toggle_sel_mode (GtkWidget *widget, gpointer data)
5540 {
5541   GtkCList *clist;
5542   gint i;
5543
5544   clist = GTK_CLIST (data);
5545
5546   if (!GTK_WIDGET_MAPPED (widget))
5547     return;
5548
5549   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
5550
5551   gtk_clist_set_selection_mode (clist, selection_modes[i]);
5552 }
5553
5554 static void 
5555 clist_click_column (GtkCList *clist, gint column, gpointer data)
5556 {
5557   if (column == 4)
5558     gtk_clist_set_column_visibility (clist, column, FALSE);
5559   else if (column == clist->sort_column)
5560     {
5561       if (clist->sort_type == GTK_SORT_ASCENDING)
5562         clist->sort_type = GTK_SORT_DESCENDING;
5563       else
5564         clist->sort_type = GTK_SORT_ASCENDING;
5565     }
5566   else
5567     gtk_clist_set_sort_column (clist, column);
5568
5569   gtk_clist_sort (clist);
5570 }
5571
5572 static void
5573 create_clist (GtkWidget *widget)
5574 {
5575   gint i;
5576   static GtkWidget *window = NULL;
5577
5578   static char *titles[] =
5579   {
5580     "auto resize", "not resizeable", "max width 100", "min width 50",
5581     "hide column", "Title 5", "Title 6", "Title 7",
5582     "Title 8",  "Title 9",  "Title 10", "Title 11"
5583   };
5584
5585   char text[TESTGTK_CLIST_COLUMNS][50];
5586   char *texts[TESTGTK_CLIST_COLUMNS];
5587
5588   GtkWidget *vbox;
5589   GtkWidget *hbox;
5590   GtkWidget *clist;
5591   GtkWidget *button;
5592   GtkWidget *separator;
5593   GtkWidget *scrolled_win;
5594   GtkWidget *check;
5595
5596   GtkWidget *undo_button;
5597   GtkWidget *label;
5598
5599   GtkStyle *style;
5600   GdkColor col1;
5601   GdkColor col2;
5602
5603   if (!window)
5604     {
5605       clist_rows = 0;
5606       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5607       gtk_window_set_screen (GTK_WINDOW (window), 
5608                              gtk_widget_get_screen (widget));
5609
5610       gtk_signal_connect (GTK_OBJECT (window), "destroy",
5611                           GTK_SIGNAL_FUNC (gtk_widget_destroyed), &window);
5612
5613       gtk_window_set_title (GTK_WINDOW (window), "clist");
5614       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5615
5616       vbox = gtk_vbox_new (FALSE, 0);
5617       gtk_container_add (GTK_CONTAINER (window), vbox);
5618
5619       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
5620       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
5621       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
5622                                       GTK_POLICY_AUTOMATIC, 
5623                                       GTK_POLICY_AUTOMATIC);
5624
5625       /* create GtkCList here so we have a pointer to throw at the 
5626        * button callbacks -- more is done with it later */
5627       clist = gtk_clist_new_with_titles (TESTGTK_CLIST_COLUMNS, titles);
5628       gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
5629       gtk_signal_connect (GTK_OBJECT (clist), "click_column",
5630                           (GtkSignalFunc) clist_click_column, NULL);
5631
5632       /* control buttons */
5633       hbox = gtk_hbox_new (FALSE, 5);
5634       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5635       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5636
5637       button = gtk_button_new_with_label ("Insert Row");
5638       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5639       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5640                           (GtkSignalFunc) insert_row_clist, (gpointer) clist);
5641
5642       button = gtk_button_new_with_label ("Add 1,000 Rows With Pixmaps");
5643       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5644       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5645                           (GtkSignalFunc) add1000_clist, (gpointer) clist);
5646
5647       button = gtk_button_new_with_label ("Add 10,000 Rows");
5648       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5649       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5650                           (GtkSignalFunc) add10000_clist, (gpointer) clist);
5651
5652       /* second layer of buttons */
5653       hbox = gtk_hbox_new (FALSE, 5);
5654       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5655       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5656
5657       button = gtk_button_new_with_label ("Clear List");
5658       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5659       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5660                           (GtkSignalFunc) clear_clist, (gpointer) clist);
5661
5662       button = gtk_button_new_with_label ("Remove Selection");
5663       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5664       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5665                           (GtkSignalFunc) clist_remove_selection,
5666                           (gpointer) clist);
5667
5668       undo_button = gtk_button_new_with_label ("Undo Selection");
5669       gtk_box_pack_start (GTK_BOX (hbox), undo_button, TRUE, TRUE, 0);
5670       gtk_signal_connect (GTK_OBJECT (undo_button), "clicked",
5671                           (GtkSignalFunc) undo_selection, (gpointer) clist);
5672
5673       button = gtk_button_new_with_label ("Warning Test");
5674       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5675       gtk_signal_connect (GTK_OBJECT (button), "clicked",
5676                           (GtkSignalFunc) clist_warning_test,(gpointer) clist);
5677
5678       /* third layer of buttons */
5679       hbox = gtk_hbox_new (FALSE, 5);
5680       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5681       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
5682
5683       check = gtk_check_button_new_with_label ("Show Title Buttons");
5684       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5685       gtk_signal_connect (GTK_OBJECT (check), "clicked",
5686                           GTK_SIGNAL_FUNC (toggle_title_buttons), clist);
5687       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5688
5689       check = gtk_check_button_new_with_label ("Reorderable");
5690       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
5691       gtk_signal_connect (GTK_OBJECT (check), "clicked",
5692                           GTK_SIGNAL_FUNC (toggle_reorderable), clist);
5693       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5694
5695       label = gtk_label_new ("Selection Mode :");
5696       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5697
5698       clist_omenu = build_option_menu (selection_mode_items, 3, 3, 
5699                                        clist_toggle_sel_mode,
5700                                        clist);
5701       gtk_box_pack_start (GTK_BOX (hbox), clist_omenu, FALSE, TRUE, 0);
5702
5703       /* 
5704        * the rest of the clist configuration
5705        */
5706
5707       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
5708       gtk_clist_set_row_height (GTK_CLIST (clist), 18);
5709       gtk_widget_set_usize (clist, -1, 300);
5710
5711       for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
5712         gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
5713
5714       gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
5715       gtk_clist_set_column_resizeable (GTK_CLIST (clist), 1, FALSE);
5716       gtk_clist_set_column_max_width (GTK_CLIST (clist), 2, 100);
5717       gtk_clist_set_column_min_width (GTK_CLIST (clist), 3, 50);
5718       gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
5719       gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
5720                                           GTK_JUSTIFY_RIGHT);
5721       gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
5722                                           GTK_JUSTIFY_CENTER);
5723       
5724       for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
5725         {
5726           texts[i] = text[i];
5727           sprintf (text[i], "Column %d", i);
5728         }
5729
5730       sprintf (text[1], "Right");
5731       sprintf (text[2], "Center");
5732
5733       col1.red   = 56000;
5734       col1.green = 0;
5735       col1.blue  = 0;
5736       col2.red   = 0;
5737       col2.green = 56000;
5738       col2.blue  = 32000;
5739
5740       style = gtk_style_new ();
5741       style->fg[GTK_STATE_NORMAL] = col1;
5742       style->base[GTK_STATE_NORMAL] = col2;
5743
5744       pango_font_description_set_size (style->font_desc, 14 * PANGO_SCALE);
5745       pango_font_description_set_weight (style->font_desc, PANGO_WEIGHT_BOLD);
5746
5747       for (i = 0; i < 10; i++)
5748         {
5749           sprintf (text[0], "CListRow %d", clist_rows++);
5750           gtk_clist_append (GTK_CLIST (clist), texts);
5751
5752           switch (i % 4)
5753             {
5754             case 2:
5755               gtk_clist_set_row_style (GTK_CLIST (clist), i, style);
5756               break;
5757             default:
5758               gtk_clist_set_cell_style (GTK_CLIST (clist), i, i % 4, style);
5759               break;
5760             }
5761         }
5762
5763       gtk_style_unref (style);
5764       
5765       separator = gtk_hseparator_new ();
5766       gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
5767
5768       hbox = gtk_hbox_new (FALSE, 0);
5769       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5770
5771       button = gtk_button_new_with_label ("close");
5772       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5773       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
5774       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
5775                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
5776                                  GTK_OBJECT (window));
5777
5778       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
5779       gtk_widget_grab_default (button);
5780     }
5781
5782   if (!GTK_WIDGET_VISIBLE (window))
5783     gtk_widget_show_all (window);
5784   else
5785     {
5786       clist_rows = 0;
5787       gtk_widget_destroy (window);
5788     }
5789 }
5790
5791 /*
5792  * GtkCTree
5793  */
5794
5795 typedef struct 
5796 {
5797   GdkPixmap *pixmap1;
5798   GdkPixmap *pixmap2;
5799   GdkPixmap *pixmap3;
5800   GdkBitmap *mask1;
5801   GdkBitmap *mask2;
5802   GdkBitmap *mask3;
5803 } CTreePixmaps;
5804
5805 static gint books = 0;
5806 static gint pages = 0;
5807
5808 static GtkWidget *book_label;
5809 static GtkWidget *page_label;
5810 static GtkWidget *sel_label;
5811 static GtkWidget *vis_label;
5812 static GtkWidget *omenu1;
5813 static GtkWidget *omenu2;
5814 static GtkWidget *omenu3;
5815 static GtkWidget *omenu4;
5816 static GtkWidget *spin1;
5817 static GtkWidget *spin2;
5818 static GtkWidget *spin3;
5819 static gint line_style;
5820
5821
5822 static CTreePixmaps *
5823 get_ctree_pixmaps (GtkCTree *ctree)
5824 {
5825   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (ctree));
5826   CTreePixmaps *pixmaps = g_object_get_data (G_OBJECT (screen), "ctree-pixmaps");
5827
5828   if (!pixmaps)
5829     {
5830       GdkColormap *colormap = gdk_screen_get_rgb_colormap (screen);
5831       pixmaps = g_new (CTreePixmaps, 1);
5832       
5833       pixmaps->pixmap1 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5834                                                                 &pixmaps->mask1, 
5835                                                                 NULL, book_closed_xpm);
5836       pixmaps->pixmap2 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5837                                                                 &pixmaps->mask2, 
5838                                                                 NULL, book_open_xpm);
5839       pixmaps->pixmap3 = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap,
5840                                                                 &pixmaps->mask3,
5841                                                                 NULL, mini_page_xpm);
5842       
5843       g_object_set_data (G_OBJECT (screen), "ctree-pixmaps", pixmaps);
5844     }
5845
5846   return pixmaps;
5847 }
5848
5849 void after_press (GtkCTree *ctree, gpointer data)
5850 {
5851   char buf[80];
5852
5853   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
5854   gtk_label_set_text (GTK_LABEL (sel_label), buf);
5855
5856   sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
5857   gtk_label_set_text (GTK_LABEL (vis_label), buf);
5858
5859   sprintf (buf, "%d", books);
5860   gtk_label_set_text (GTK_LABEL (book_label), buf);
5861
5862   sprintf (buf, "%d", pages);
5863   gtk_label_set_text (GTK_LABEL (page_label), buf);
5864 }
5865
5866 void after_move (GtkCTree *ctree, GtkCTreeNode *child, GtkCTreeNode *parent, 
5867                  GtkCTreeNode *sibling, gpointer data)
5868 {
5869   char *source;
5870   char *target1;
5871   char *target2;
5872
5873   gtk_ctree_get_node_info (ctree, child, &source, 
5874                            NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5875   if (parent)
5876     gtk_ctree_get_node_info (ctree, parent, &target1, 
5877                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5878   if (sibling)
5879     gtk_ctree_get_node_info (ctree, sibling, &target2, 
5880                              NULL, NULL, NULL, NULL, NULL, NULL, NULL);
5881
5882   g_print ("Moving \"%s\" to \"%s\" with sibling \"%s\".\n", source,
5883            (parent) ? target1 : "nil", (sibling) ? target2 : "nil");
5884 }
5885
5886 void count_items (GtkCTree *ctree, GtkCTreeNode *list)
5887 {
5888   if (GTK_CTREE_ROW (list)->is_leaf)
5889     pages--;
5890   else
5891     books--;
5892 }
5893
5894 void expand_all (GtkWidget *widget, GtkCTree *ctree)
5895 {
5896   gtk_ctree_expand_recursive (ctree, NULL);
5897   after_press (ctree, NULL);
5898 }
5899
5900 void collapse_all (GtkWidget *widget, GtkCTree *ctree)
5901 {
5902   gtk_ctree_collapse_recursive (ctree, NULL);
5903   after_press (ctree, NULL);
5904 }
5905
5906 void select_all (GtkWidget *widget, GtkCTree *ctree)
5907 {
5908   gtk_ctree_select_recursive (ctree, NULL);
5909   after_press (ctree, NULL);
5910 }
5911
5912 void change_style (GtkWidget *widget, GtkCTree *ctree)
5913 {
5914   static GtkStyle *style1 = NULL;
5915   static GtkStyle *style2 = NULL;
5916
5917   GtkCTreeNode *node;
5918   GdkColor col1;
5919   GdkColor col2;
5920
5921   if (GTK_CLIST (ctree)->focus_row >= 0)
5922     node = GTK_CTREE_NODE
5923       (g_list_nth (GTK_CLIST (ctree)->row_list,GTK_CLIST (ctree)->focus_row));
5924   else
5925     node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list);
5926
5927   if (!node)
5928     return;
5929
5930   if (!style1)
5931     {
5932       col1.red   = 0;
5933       col1.green = 56000;
5934       col1.blue  = 0;
5935       col2.red   = 32000;
5936       col2.green = 0;
5937       col2.blue  = 56000;
5938
5939       style1 = gtk_style_new ();
5940       style1->base[GTK_STATE_NORMAL] = col1;
5941       style1->fg[GTK_STATE_SELECTED] = col2;
5942
5943       style2 = gtk_style_new ();
5944       style2->base[GTK_STATE_SELECTED] = col2;
5945       style2->fg[GTK_STATE_NORMAL] = col1;
5946       style2->base[GTK_STATE_NORMAL] = col2;
5947       pango_font_description_free (style2->font_desc);
5948       style2->font_desc = pango_font_description_from_string ("courier 30");
5949     }
5950
5951   gtk_ctree_node_set_cell_style (ctree, node, 1, style1);
5952   gtk_ctree_node_set_cell_style (ctree, node, 0, style2);
5953
5954   if (GTK_CTREE_ROW (node)->children)
5955     gtk_ctree_node_set_row_style (ctree, GTK_CTREE_ROW (node)->children,
5956                                   style2);
5957 }
5958
5959 void unselect_all (GtkWidget *widget, GtkCTree *ctree)
5960 {
5961   gtk_ctree_unselect_recursive (ctree, NULL);
5962   after_press (ctree, NULL);
5963 }
5964
5965 void remove_selection (GtkWidget *widget, GtkCTree *ctree)
5966 {
5967   GtkCList *clist;
5968   GtkCTreeNode *node;
5969
5970   clist = GTK_CLIST (ctree);
5971
5972   gtk_clist_freeze (clist);
5973
5974   while (clist->selection)
5975     {
5976       node = clist->selection->data;
5977
5978       if (GTK_CTREE_ROW (node)->is_leaf)
5979         pages--;
5980       else
5981         gtk_ctree_post_recursive (ctree, node,
5982                                   (GtkCTreeFunc) count_items, NULL);
5983
5984       gtk_ctree_remove_node (ctree, node);
5985
5986       if (clist->selection_mode == GTK_SELECTION_BROWSE)
5987         break;
5988     }
5989
5990   if (clist->selection_mode == GTK_SELECTION_EXTENDED && !clist->selection &&
5991       clist->focus_row >= 0)
5992     {
5993       node = gtk_ctree_node_nth (ctree, clist->focus_row);
5994
5995       if (node)
5996         gtk_ctree_select (ctree, node);
5997     }
5998     
5999   gtk_clist_thaw (clist);
6000   after_press (ctree, NULL);
6001 }
6002
6003 struct _ExportStruct {
6004   gchar *tree;
6005   gchar *info;
6006   gboolean is_leaf;
6007 };
6008
6009 typedef struct _ExportStruct ExportStruct;
6010
6011 gboolean
6012 gnode2ctree (GtkCTree   *ctree,
6013              guint       depth,
6014              GNode        *gnode,
6015              GtkCTreeNode *cnode,
6016              gpointer    data)
6017 {
6018   ExportStruct *es;
6019   GdkPixmap *pixmap_closed;
6020   GdkBitmap *mask_closed;
6021   GdkPixmap *pixmap_opened;
6022   GdkBitmap *mask_opened;
6023   CTreePixmaps *pixmaps;
6024
6025   if (!cnode || !gnode || (!(es = gnode->data)))
6026     return FALSE;
6027
6028   pixmaps = get_ctree_pixmaps (ctree);
6029
6030   if (es->is_leaf)
6031     {
6032       pixmap_closed = pixmaps->pixmap3;
6033       mask_closed = pixmaps->mask3;
6034       pixmap_opened = NULL;
6035       mask_opened = NULL;
6036     }
6037   else
6038     {
6039       pixmap_closed = pixmaps->pixmap1;
6040       mask_closed = pixmaps->mask1;
6041       pixmap_opened = pixmaps->pixmap2;
6042       mask_opened = pixmaps->mask2;
6043     }
6044
6045   gtk_ctree_set_node_info (ctree, cnode, es->tree, 2, pixmap_closed,
6046                            mask_closed, pixmap_opened, mask_opened,
6047                            es->is_leaf, (depth < 3));
6048   gtk_ctree_node_set_text (ctree, cnode, 1, es->info);
6049   g_free (es);
6050   gnode->data = NULL;
6051
6052   return TRUE;
6053 }
6054
6055 gboolean
6056 ctree2gnode (GtkCTree   *ctree,
6057              guint       depth,
6058              GNode        *gnode,
6059              GtkCTreeNode *cnode,
6060              gpointer    data)
6061 {
6062   ExportStruct *es;
6063
6064   if (!cnode || !gnode)
6065     return FALSE;
6066   
6067   es = g_new (ExportStruct, 1);
6068   gnode->data = es;
6069   es->is_leaf = GTK_CTREE_ROW (cnode)->is_leaf;
6070   es->tree = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[0])->text;
6071   es->info = GTK_CELL_PIXTEXT (GTK_CTREE_ROW (cnode)->row.cell[1])->text;
6072   return TRUE;
6073 }
6074
6075 void export_ctree (GtkWidget *widget, GtkCTree *ctree)
6076 {
6077   char *title[] = { "Tree" , "Info" };
6078   static GtkWidget *export_window = NULL;
6079   static GtkCTree *export_ctree;
6080   GtkWidget *vbox;
6081   GtkWidget *scrolled_win;
6082   GtkWidget *button;
6083   GtkWidget *sep;
6084   GNode *gnode;
6085   GtkCTreeNode *node;
6086
6087   if (!export_window)
6088     {
6089       export_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6090
6091       gtk_window_set_screen (GTK_WINDOW (export_window),
6092                              gtk_widget_get_screen (widget));
6093   
6094       gtk_signal_connect (GTK_OBJECT (export_window), "destroy",
6095                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
6096                           &export_window);
6097
6098       gtk_window_set_title (GTK_WINDOW (export_window), "exported ctree");
6099       gtk_container_set_border_width (GTK_CONTAINER (export_window), 5);
6100
6101       vbox = gtk_vbox_new (FALSE, 0);
6102       gtk_container_add (GTK_CONTAINER (export_window), vbox);
6103       
6104       button = gtk_button_new_with_label ("Close");
6105       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, TRUE, 0);
6106
6107       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6108                                  (GtkSignalFunc) gtk_widget_destroy,
6109                                  GTK_OBJECT(export_window));
6110
6111       sep = gtk_hseparator_new ();
6112       gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, TRUE, 10);
6113
6114       export_ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6115       gtk_ctree_set_line_style (export_ctree, GTK_CTREE_LINES_DOTTED);
6116
6117       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6118       gtk_container_add (GTK_CONTAINER (scrolled_win),
6119                          GTK_WIDGET (export_ctree));
6120       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6121                                       GTK_POLICY_AUTOMATIC,
6122                                       GTK_POLICY_AUTOMATIC);
6123       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6124       gtk_clist_set_selection_mode (GTK_CLIST (export_ctree),
6125                                     GTK_SELECTION_EXTENDED);
6126       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 0, 200);
6127       gtk_clist_set_column_width (GTK_CLIST (export_ctree), 1, 200);
6128       gtk_widget_set_usize (GTK_WIDGET (export_ctree), 300, 200);
6129     }
6130
6131   if (!GTK_WIDGET_VISIBLE (export_window))
6132     gtk_widget_show_all (export_window);
6133       
6134   gtk_clist_clear (GTK_CLIST (export_ctree));
6135
6136   node = GTK_CTREE_NODE (g_list_nth (GTK_CLIST (ctree)->row_list,
6137                                      GTK_CLIST (ctree)->focus_row));
6138   if (!node)
6139     return;
6140
6141   gnode = gtk_ctree_export_to_gnode (ctree, NULL, NULL, node,
6142                                      ctree2gnode, NULL);
6143   if (gnode)
6144     {
6145       gtk_ctree_insert_gnode (export_ctree, NULL, NULL, gnode,
6146                               gnode2ctree, NULL);
6147       g_node_destroy (gnode);
6148     }
6149 }
6150
6151 void change_indent (GtkWidget *widget, GtkCTree *ctree)
6152 {
6153   gtk_ctree_set_indent (ctree, GTK_ADJUSTMENT (widget)->value);
6154 }
6155
6156 void change_spacing (GtkWidget *widget, GtkCTree *ctree)
6157 {
6158   gtk_ctree_set_spacing (ctree, GTK_ADJUSTMENT (widget)->value);
6159 }
6160
6161 void change_row_height (GtkWidget *widget, GtkCList *clist)
6162 {
6163   gtk_clist_set_row_height (clist, GTK_ADJUSTMENT (widget)->value);
6164 }
6165
6166 void set_background (GtkCTree *ctree, GtkCTreeNode *node, gpointer data)
6167 {
6168   GtkStyle *style = NULL;
6169   
6170   if (!node)
6171     return;
6172   
6173   if (ctree->line_style != GTK_CTREE_LINES_TABBED)
6174     {
6175       if (!GTK_CTREE_ROW (node)->is_leaf)
6176         style = GTK_CTREE_ROW (node)->row.data;
6177       else if (GTK_CTREE_ROW (node)->parent)
6178         style = GTK_CTREE_ROW (GTK_CTREE_ROW (node)->parent)->row.data;
6179     }
6180
6181   gtk_ctree_node_set_row_style (ctree, node, style);
6182 }
6183
6184 void 
6185 ctree_toggle_line_style (GtkWidget *widget, gpointer data)
6186 {
6187   GtkCTree *ctree;
6188   gint i;
6189
6190   ctree = GTK_CTREE (data);
6191
6192   if (!GTK_WIDGET_MAPPED (widget))
6193     return;
6194
6195   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6196
6197   if ((ctree->line_style == GTK_CTREE_LINES_TABBED && 
6198        ((GtkCTreeLineStyle) i) != GTK_CTREE_LINES_TABBED) ||
6199       (ctree->line_style != GTK_CTREE_LINES_TABBED && 
6200        ((GtkCTreeLineStyle) i) == GTK_CTREE_LINES_TABBED))
6201     gtk_ctree_pre_recursive (ctree, NULL, set_background, NULL);
6202   gtk_ctree_set_line_style (ctree, i);
6203   line_style = i;
6204 }
6205
6206 void 
6207 ctree_toggle_expander_style (GtkWidget *widget, gpointer data)
6208 {
6209   GtkCTree *ctree;
6210   gint i;
6211
6212   ctree = GTK_CTREE (data);
6213
6214   if (!GTK_WIDGET_MAPPED (widget))
6215     return;
6216   
6217   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6218   
6219   gtk_ctree_set_expander_style (ctree, (GtkCTreeExpanderStyle) i);
6220 }
6221
6222 void 
6223 ctree_toggle_justify (GtkWidget *widget, gpointer data)
6224 {
6225   GtkCTree *ctree;
6226   gint i;
6227
6228   ctree = GTK_CTREE (data);
6229
6230   if (!GTK_WIDGET_MAPPED (widget))
6231     return;
6232
6233   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6234
6235   gtk_clist_set_column_justification (GTK_CLIST (ctree), ctree->tree_column, 
6236                                       (GtkJustification) i);
6237 }
6238
6239 void 
6240 ctree_toggle_sel_mode (GtkWidget *widget, gpointer data)
6241 {
6242   GtkCTree *ctree;
6243   gint i;
6244
6245   ctree = GTK_CTREE (data);
6246
6247   if (!GTK_WIDGET_MAPPED (widget))
6248     return;
6249
6250   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
6251
6252   gtk_clist_set_selection_mode (GTK_CLIST (ctree), selection_modes[i]);
6253   after_press (ctree, NULL);
6254 }
6255     
6256 void build_recursive (GtkCTree *ctree, gint cur_depth, gint depth, 
6257                       gint num_books, gint num_pages, GtkCTreeNode *parent)
6258 {
6259   gchar *text[2];
6260   gchar buf1[60];
6261   gchar buf2[60];
6262   GtkCTreeNode *sibling;
6263   CTreePixmaps *pixmaps;
6264   gint i;
6265
6266   text[0] = buf1;
6267   text[1] = buf2;
6268   sibling = NULL;
6269
6270   pixmaps = get_ctree_pixmaps (ctree);
6271
6272   for (i = num_pages + num_books; i > num_books; i--)
6273     {
6274       pages++;
6275       sprintf (buf1, "Page %02d", (gint) rand() % 100);
6276       sprintf (buf2, "Item %d-%d", cur_depth, i);
6277       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6278                                        pixmaps->pixmap3, pixmaps->mask3, NULL, NULL,
6279                                        TRUE, FALSE);
6280
6281       if (parent && ctree->line_style == GTK_CTREE_LINES_TABBED)
6282         gtk_ctree_node_set_row_style (ctree, sibling,
6283                                       GTK_CTREE_ROW (parent)->row.style);
6284     }
6285
6286   if (cur_depth == depth)
6287     return;
6288
6289   for (i = num_books; i > 0; i--)
6290     {
6291       GtkStyle *style;
6292
6293       books++;
6294       sprintf (buf1, "Book %02d", (gint) rand() % 100);
6295       sprintf (buf2, "Item %d-%d", cur_depth, i);
6296       sibling = gtk_ctree_insert_node (ctree, parent, sibling, text, 5,
6297                                        pixmaps->pixmap1, pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2,
6298                                        FALSE, FALSE);
6299
6300       style = gtk_style_new ();
6301       switch (cur_depth % 3)
6302         {
6303         case 0:
6304           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6305           style->base[GTK_STATE_NORMAL].green = 0;
6306           style->base[GTK_STATE_NORMAL].blue  = 65535 - ((i * 10000) % 65535);
6307           break;
6308         case 1:
6309           style->base[GTK_STATE_NORMAL].red   = 10000 * (cur_depth % 6);
6310           style->base[GTK_STATE_NORMAL].green = 65535 - ((i * 10000) % 65535);
6311           style->base[GTK_STATE_NORMAL].blue  = 0;
6312           break;
6313         default:
6314           style->base[GTK_STATE_NORMAL].red   = 65535 - ((i * 10000) % 65535);
6315           style->base[GTK_STATE_NORMAL].green = 0;
6316           style->base[GTK_STATE_NORMAL].blue  = 10000 * (cur_depth % 6);
6317           break;
6318         }
6319       gtk_ctree_node_set_row_data_full (ctree, sibling, style,
6320                                         (GtkDestroyNotify) gtk_style_unref);
6321
6322       if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6323         gtk_ctree_node_set_row_style (ctree, sibling, style);
6324
6325       build_recursive (ctree, cur_depth + 1, depth, num_books, num_pages,
6326                        sibling);
6327     }
6328 }
6329
6330 void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
6331 {
6332   gchar *text [2];
6333   gchar label1[] = "Root";
6334   gchar label2[] = "";
6335   GtkCTreeNode *parent;
6336   GtkStyle *style;
6337   guint b, d, p, n;
6338   CTreePixmaps *pixmaps;
6339
6340   pixmaps = get_ctree_pixmaps (ctree);
6341
6342   text[0] = label1;
6343   text[1] = label2;
6344   
6345   d = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1)); 
6346   b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
6347   p = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin3));
6348
6349   n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
6350
6351   if (n > 100000)
6352     {
6353       g_print ("%d total items? Try less\n",n);
6354       return;
6355     }
6356
6357   gtk_clist_freeze (GTK_CLIST (ctree));
6358   gtk_clist_clear (GTK_CLIST (ctree));
6359
6360   books = 1;
6361   pages = 0;
6362
6363   parent = gtk_ctree_insert_node (ctree, NULL, NULL, text, 5, pixmaps->pixmap1,
6364                                   pixmaps->mask1, pixmaps->pixmap2, pixmaps->mask2, FALSE, TRUE);
6365
6366   style = gtk_style_new ();
6367   style->base[GTK_STATE_NORMAL].red   = 0;
6368   style->base[GTK_STATE_NORMAL].green = 45000;
6369   style->base[GTK_STATE_NORMAL].blue  = 55000;
6370   gtk_ctree_node_set_row_data_full (ctree, parent, style,
6371                                     (GtkDestroyNotify) gtk_style_unref);
6372
6373   if (ctree->line_style == GTK_CTREE_LINES_TABBED)
6374     gtk_ctree_node_set_row_style (ctree, parent, style);
6375
6376   build_recursive (ctree, 1, d, b, p, parent);
6377   gtk_clist_thaw (GTK_CLIST (ctree));
6378   after_press (ctree, NULL);
6379 }
6380
6381 static void 
6382 ctree_click_column (GtkCTree *ctree, gint column, gpointer data)
6383 {
6384   GtkCList *clist;
6385
6386   clist = GTK_CLIST (ctree);
6387
6388   if (column == clist->sort_column)
6389     {
6390       if (clist->sort_type == GTK_SORT_ASCENDING)
6391         clist->sort_type = GTK_SORT_DESCENDING;
6392       else
6393         clist->sort_type = GTK_SORT_ASCENDING;
6394     }
6395   else
6396     gtk_clist_set_sort_column (clist, column);
6397
6398   gtk_ctree_sort_recursive (ctree, NULL);
6399 }
6400
6401 void create_ctree (GtkWidget *widget)
6402 {
6403   static GtkWidget *window = NULL;
6404   GtkTooltips *tooltips;
6405   GtkCTree *ctree;
6406   GtkWidget *scrolled_win;
6407   GtkWidget *vbox;
6408   GtkWidget *bbox;
6409   GtkWidget *mbox;
6410   GtkWidget *hbox;
6411   GtkWidget *hbox2;
6412   GtkWidget *frame;
6413   GtkWidget *label;
6414   GtkWidget *button;
6415   GtkWidget *check;
6416   GtkAdjustment *adj;
6417   GtkWidget *spinner;
6418
6419   char *title[] = { "Tree" , "Info" };
6420   char buf[80];
6421
6422   static gchar *items1[] =
6423   {
6424     "No lines",
6425     "Solid",
6426     "Dotted",
6427     "Tabbed"
6428   };
6429
6430   static gchar *items2[] =
6431   {
6432     "None",
6433     "Square",
6434     "Triangle",
6435     "Circular"
6436   };
6437
6438   static gchar *items3[] =
6439   {
6440     "Left",
6441     "Right"
6442   };
6443   
6444   if (!window)
6445     {
6446       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6447       gtk_window_set_screen (GTK_WINDOW (window), 
6448                              gtk_widget_get_screen (widget));
6449
6450       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6451                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
6452                           &window);
6453
6454       gtk_window_set_title (GTK_WINDOW (window), "GtkCTree");
6455       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6456
6457       tooltips = gtk_tooltips_new ();
6458       gtk_object_ref (GTK_OBJECT (tooltips));
6459       gtk_object_sink (GTK_OBJECT (tooltips));
6460
6461       gtk_object_set_data_full (GTK_OBJECT (window), "tooltips", tooltips,
6462                                 (GtkDestroyNotify) gtk_object_unref);
6463
6464       vbox = gtk_vbox_new (FALSE, 0);
6465       gtk_container_add (GTK_CONTAINER (window), vbox);
6466
6467       hbox = gtk_hbox_new (FALSE, 5);
6468       gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
6469       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
6470       
6471       label = gtk_label_new ("Depth :");
6472       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6473       
6474       adj = (GtkAdjustment *) gtk_adjustment_new (4, 1, 10, 1, 5, 0);
6475       spin1 = gtk_spin_button_new (adj, 0, 0);
6476       gtk_box_pack_start (GTK_BOX (hbox), spin1, FALSE, TRUE, 5);
6477   
6478       label = gtk_label_new ("Books :");
6479       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6480       
6481       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
6482       spin2 = gtk_spin_button_new (adj, 0, 0);
6483       gtk_box_pack_start (GTK_BOX (hbox), spin2, FALSE, TRUE, 5);
6484
6485       label = gtk_label_new ("Pages :");
6486       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
6487       
6488       adj = (GtkAdjustment *) gtk_adjustment_new (5, 1, 20, 1, 5, 0);
6489       spin3 = gtk_spin_button_new (adj, 0, 0);
6490       gtk_box_pack_start (GTK_BOX (hbox), spin3, FALSE, TRUE, 5);
6491
6492       button = gtk_button_new_with_label ("Close");
6493       gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6494
6495       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6496                                  (GtkSignalFunc) gtk_widget_destroy,
6497                                  GTK_OBJECT(window));
6498
6499       button = gtk_button_new_with_label ("Rebuild Tree");
6500       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6501
6502       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
6503       gtk_container_set_border_width (GTK_CONTAINER (scrolled_win), 5);
6504       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
6505                                       GTK_POLICY_AUTOMATIC,
6506                                       GTK_POLICY_ALWAYS);
6507       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
6508
6509       ctree = GTK_CTREE (gtk_ctree_new_with_titles (2, 0, title));
6510       gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (ctree));
6511
6512       gtk_clist_set_column_auto_resize (GTK_CLIST (ctree), 0, TRUE);
6513       gtk_clist_set_column_width (GTK_CLIST (ctree), 1, 200);
6514       gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
6515       gtk_ctree_set_line_style (ctree, GTK_CTREE_LINES_DOTTED);
6516       line_style = GTK_CTREE_LINES_DOTTED;
6517
6518       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6519                           GTK_SIGNAL_FUNC (rebuild_tree), ctree);
6520       gtk_signal_connect (GTK_OBJECT (ctree), "click_column",
6521                           (GtkSignalFunc) ctree_click_column, NULL);
6522
6523       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_press_event",
6524                                 GTK_SIGNAL_FUNC (after_press), NULL);
6525       gtk_signal_connect_after (GTK_OBJECT (ctree), "button_release_event",
6526                                 GTK_SIGNAL_FUNC (after_press), NULL);
6527       gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
6528                                 GTK_SIGNAL_FUNC (after_move), NULL);
6529       gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
6530                                 GTK_SIGNAL_FUNC (after_press), NULL);
6531       gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
6532                                 GTK_SIGNAL_FUNC (after_press), NULL);
6533       gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
6534                                 GTK_SIGNAL_FUNC (after_press), NULL);
6535       gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
6536                                 GTK_SIGNAL_FUNC (after_press), NULL);
6537       gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
6538                                 GTK_SIGNAL_FUNC (after_press), NULL);
6539
6540       bbox = gtk_hbox_new (FALSE, 5);
6541       gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
6542       gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, TRUE, 0);
6543
6544       mbox = gtk_vbox_new (TRUE, 5);
6545       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6546
6547       label = gtk_label_new ("Row Height :");
6548       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6549
6550       label = gtk_label_new ("Indent :");
6551       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6552
6553       label = gtk_label_new ("Spacing :");
6554       gtk_box_pack_start (GTK_BOX (mbox), label, FALSE, FALSE, 0);
6555
6556       mbox = gtk_vbox_new (TRUE, 5);
6557       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6558
6559       adj = (GtkAdjustment *) gtk_adjustment_new (20, 12, 100, 1, 10, 0);
6560       spinner = gtk_spin_button_new (adj, 0, 0);
6561       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6562       gtk_tooltips_set_tip (tooltips, spinner,
6563                             "Row height of list items", NULL);
6564       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6565                           GTK_SIGNAL_FUNC (change_row_height), ctree);
6566       gtk_clist_set_row_height ( GTK_CLIST (ctree), adj->value);
6567
6568       adj = (GtkAdjustment *) gtk_adjustment_new (20, 0, 60, 1, 10, 0);
6569       spinner = gtk_spin_button_new (adj, 0, 0);
6570       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6571       gtk_tooltips_set_tip (tooltips, spinner, "Tree Indentation.", NULL);
6572       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6573                           GTK_SIGNAL_FUNC (change_indent), ctree);
6574
6575       adj = (GtkAdjustment *) gtk_adjustment_new (5, 0, 60, 1, 10, 0);
6576       spinner = gtk_spin_button_new (adj, 0, 0);
6577       gtk_box_pack_start (GTK_BOX (mbox), spinner, FALSE, FALSE, 5);
6578       gtk_tooltips_set_tip (tooltips, spinner, "Tree Spacing.", NULL);
6579       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
6580                           GTK_SIGNAL_FUNC (change_spacing), ctree);
6581
6582       mbox = gtk_vbox_new (TRUE, 5);
6583       gtk_box_pack_start (GTK_BOX (bbox), mbox, FALSE, TRUE, 0);
6584
6585       hbox = gtk_hbox_new (FALSE, 5);
6586       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6587
6588       button = gtk_button_new_with_label ("Expand All");
6589       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6590       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6591                           GTK_SIGNAL_FUNC (expand_all), ctree);
6592
6593       button = gtk_button_new_with_label ("Collapse All");
6594       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6595       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6596                           GTK_SIGNAL_FUNC (collapse_all), ctree);
6597
6598       button = gtk_button_new_with_label ("Change Style");
6599       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6600       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6601                           GTK_SIGNAL_FUNC (change_style), ctree);
6602
6603       button = gtk_button_new_with_label ("Export Tree");
6604       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6605       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6606                           GTK_SIGNAL_FUNC (export_ctree), ctree);
6607
6608       hbox = gtk_hbox_new (FALSE, 5);
6609       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6610
6611       button = gtk_button_new_with_label ("Select All");
6612       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6613       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6614                           GTK_SIGNAL_FUNC (select_all), ctree);
6615
6616       button = gtk_button_new_with_label ("Unselect All");
6617       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6618       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6619                           GTK_SIGNAL_FUNC (unselect_all), ctree);
6620
6621       button = gtk_button_new_with_label ("Remove Selection");
6622       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
6623       gtk_signal_connect (GTK_OBJECT (button), "clicked",
6624                           GTK_SIGNAL_FUNC (remove_selection), ctree);
6625
6626       check = gtk_check_button_new_with_label ("Reorderable");
6627       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
6628       gtk_tooltips_set_tip (tooltips, check,
6629                             "Tree items can be reordered by dragging.", NULL);
6630       gtk_signal_connect (GTK_OBJECT (check), "clicked",
6631                           GTK_SIGNAL_FUNC (toggle_reorderable), ctree);
6632       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
6633
6634       hbox = gtk_hbox_new (TRUE, 5);
6635       gtk_box_pack_start (GTK_BOX (mbox), hbox, FALSE, FALSE, 0);
6636
6637       omenu1 = build_option_menu (items1, 4, 2, 
6638                                   ctree_toggle_line_style,
6639                                   ctree);
6640       gtk_box_pack_start (GTK_BOX (hbox), omenu1, FALSE, TRUE, 0);
6641       gtk_tooltips_set_tip (tooltips, omenu1, "The tree's line style.", NULL);
6642
6643       omenu2 = build_option_menu (items2, 4, 1, 
6644                                   ctree_toggle_expander_style,
6645                                   ctree);
6646       gtk_box_pack_start (GTK_BOX (hbox), omenu2, FALSE, TRUE, 0);
6647       gtk_tooltips_set_tip (tooltips, omenu2, "The tree's expander style.",
6648                             NULL);
6649
6650       omenu3 = build_option_menu (items3, 2, 0, 
6651                                   ctree_toggle_justify, ctree);
6652       gtk_box_pack_start (GTK_BOX (hbox), omenu3, FALSE, TRUE, 0);
6653       gtk_tooltips_set_tip (tooltips, omenu3, "The tree's justification.",
6654                             NULL);
6655
6656       omenu4 = build_option_menu (selection_mode_items, 3, 3, 
6657                                   ctree_toggle_sel_mode, ctree);
6658       gtk_box_pack_start (GTK_BOX (hbox), omenu4, FALSE, TRUE, 0);
6659       gtk_tooltips_set_tip (tooltips, omenu4, "The list's selection mode.",
6660                             NULL);
6661
6662       gtk_widget_realize (window);
6663       
6664       gtk_widget_set_usize (GTK_WIDGET (ctree), 0, 300);
6665
6666       frame = gtk_frame_new (NULL);
6667       gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
6668       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
6669       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
6670
6671       hbox = gtk_hbox_new (TRUE, 2);
6672       gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
6673       gtk_container_add (GTK_CONTAINER (frame), hbox);
6674
6675       frame = gtk_frame_new (NULL);
6676       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6677       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6678
6679       hbox2 = gtk_hbox_new (FALSE, 0);
6680       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6681       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6682
6683       label = gtk_label_new ("Books :");
6684       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6685
6686       sprintf (buf, "%d", books);
6687       book_label = gtk_label_new (buf);
6688       gtk_box_pack_end (GTK_BOX (hbox2), book_label, FALSE, TRUE, 5);
6689
6690       frame = gtk_frame_new (NULL);
6691       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6692       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6693
6694       hbox2 = gtk_hbox_new (FALSE, 0);
6695       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6696       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6697
6698       label = gtk_label_new ("Pages :");
6699       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6700
6701       sprintf (buf, "%d", pages);
6702       page_label = gtk_label_new (buf);
6703       gtk_box_pack_end (GTK_BOX (hbox2), page_label, FALSE, TRUE, 5);
6704
6705       frame = gtk_frame_new (NULL);
6706       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6707       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6708
6709       hbox2 = gtk_hbox_new (FALSE, 0);
6710       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6711       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6712
6713       label = gtk_label_new ("Selected :");
6714       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6715
6716       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->selection));
6717       sel_label = gtk_label_new (buf);
6718       gtk_box_pack_end (GTK_BOX (hbox2), sel_label, FALSE, TRUE, 5);
6719
6720       frame = gtk_frame_new (NULL);
6721       gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
6722       gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
6723
6724       hbox2 = gtk_hbox_new (FALSE, 0);
6725       gtk_container_set_border_width (GTK_CONTAINER (hbox2), 2);
6726       gtk_container_add (GTK_CONTAINER (frame), hbox2);
6727
6728       label = gtk_label_new ("Visible :");
6729       gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 0);
6730
6731       sprintf (buf, "%d", g_list_length (GTK_CLIST (ctree)->row_list));
6732       vis_label = gtk_label_new (buf);
6733       gtk_box_pack_end (GTK_BOX (hbox2), vis_label, FALSE, TRUE, 5);
6734
6735       rebuild_tree (NULL, ctree);
6736     }
6737
6738   if (!GTK_WIDGET_VISIBLE (window))
6739     gtk_widget_show_all (window);
6740   else
6741     gtk_widget_destroy (window);
6742 }
6743
6744 /*
6745  * GtkColorSelection
6746  */
6747
6748 void
6749 color_selection_ok (GtkWidget               *w,
6750                     GtkColorSelectionDialog *cs)
6751 {
6752   GtkColorSelection *colorsel;
6753   gdouble color[4];
6754
6755   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6756
6757   gtk_color_selection_get_color(colorsel,color);
6758   gtk_color_selection_set_color(colorsel,color);
6759 }
6760
6761 void
6762 color_selection_changed (GtkWidget *w,
6763                          GtkColorSelectionDialog *cs)
6764 {
6765   GtkColorSelection *colorsel;
6766   gdouble color[4];
6767
6768   colorsel=GTK_COLOR_SELECTION(cs->colorsel);
6769   gtk_color_selection_get_color(colorsel,color);
6770 }
6771
6772 static void
6773 opacity_toggled_cb (GtkWidget *w,
6774                     GtkColorSelectionDialog *cs)
6775 {
6776   GtkColorSelection *colorsel;
6777
6778   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6779   gtk_color_selection_set_has_opacity_control (colorsel,
6780                                                gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6781 }
6782
6783 static void
6784 palette_toggled_cb (GtkWidget *w,
6785                     GtkColorSelectionDialog *cs)
6786 {
6787   GtkColorSelection *colorsel;
6788
6789   colorsel = GTK_COLOR_SELECTION (cs->colorsel);
6790   gtk_color_selection_set_has_palette (colorsel,
6791                                        gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
6792 }
6793
6794 void
6795 create_color_selection (GtkWidget *widget)
6796 {
6797   static GtkWidget *window = NULL;
6798
6799   if (!window)
6800     {
6801       GtkWidget *options_hbox;
6802       GtkWidget *check_button;
6803       
6804       window = gtk_color_selection_dialog_new ("color selection dialog");
6805       gtk_window_set_screen (GTK_WINDOW (window), 
6806                              gtk_widget_get_screen (widget));
6807                              
6808       gtk_widget_show (GTK_COLOR_SELECTION_DIALOG (window)->help_button);
6809
6810       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6811
6812       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6813                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6814                           &window);
6815
6816       options_hbox = gtk_hbox_new (FALSE, 0);
6817       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), options_hbox, FALSE, FALSE, 0);
6818       gtk_container_set_border_width (GTK_CONTAINER (options_hbox), 10);
6819       
6820       check_button = gtk_check_button_new_with_label ("Show Opacity");
6821       gtk_box_pack_start (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6822       gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6823                           GTK_SIGNAL_FUNC (opacity_toggled_cb), window);
6824
6825       check_button = gtk_check_button_new_with_label ("Show Palette");
6826       gtk_box_pack_end (GTK_BOX (options_hbox), check_button, FALSE, FALSE, 0);
6827       gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6828                           GTK_SIGNAL_FUNC (palette_toggled_cb), window);
6829
6830       gtk_signal_connect (
6831         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
6832         "color_changed",
6833         GTK_SIGNAL_FUNC(color_selection_changed),
6834         window);
6835
6836       gtk_signal_connect (
6837         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
6838         "clicked",
6839         GTK_SIGNAL_FUNC(color_selection_ok),
6840         window);
6841
6842       gtk_signal_connect_object (
6843         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
6844         "clicked",
6845         GTK_SIGNAL_FUNC(gtk_widget_destroy),
6846         GTK_OBJECT (window));
6847     }
6848
6849   if (!GTK_WIDGET_VISIBLE (window))
6850     gtk_widget_show_all (window);
6851   else
6852     gtk_widget_destroy (window);
6853 }
6854
6855 /*
6856  * GtkFileSelection
6857  */
6858
6859 void
6860 show_fileops (GtkWidget        *widget,
6861               GtkFileSelection *fs)
6862 {
6863   gboolean show_ops;
6864
6865   show_ops = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6866
6867   if (show_ops)
6868     gtk_file_selection_show_fileop_buttons (fs);
6869   else
6870     gtk_file_selection_hide_fileop_buttons (fs);
6871 }
6872
6873 void
6874 select_multiple (GtkWidget        *widget,
6875                  GtkFileSelection *fs)
6876 {
6877   gboolean select_multiple;
6878
6879   select_multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6880   gtk_file_selection_set_select_multiple (fs, select_multiple);
6881 }
6882
6883 void
6884 file_selection_ok (GtkFileSelection *fs)
6885 {
6886   int i;
6887   gchar **selections;
6888
6889   selections = gtk_file_selection_get_selections (fs);
6890
6891   for (i = 0; selections[i] != NULL; i++)
6892     g_print ("%s\n", selections[i]);
6893
6894   g_strfreev (selections);
6895
6896   gtk_widget_destroy (GTK_WIDGET (fs));
6897 }
6898
6899 void
6900 create_file_selection (GtkWidget *widget)
6901 {
6902   static GtkWidget *window = NULL;
6903   GtkWidget *button;
6904
6905   if (!window)
6906     {
6907       window = gtk_file_selection_new ("file selection dialog");
6908       gtk_window_set_screen (GTK_WINDOW (window),
6909                              gtk_widget_get_screen (widget));
6910
6911       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
6912
6913       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6914
6915       g_signal_connect (window, "destroy",
6916                         G_CALLBACK (gtk_widget_destroyed),
6917                         &window);
6918
6919       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button,
6920                                 "clicked",
6921                                 G_CALLBACK (file_selection_ok),
6922                                 window);
6923       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button,
6924                                 "clicked",
6925                                 G_CALLBACK (gtk_widget_destroy),
6926                                 window);
6927       
6928       button = gtk_check_button_new_with_label ("Show Fileops");
6929       g_signal_connect (button, "toggled",
6930                         G_CALLBACK (show_fileops),
6931                         window);
6932       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6933                           button, FALSE, FALSE, 0);
6934       gtk_widget_show (button);
6935
6936       button = gtk_check_button_new_with_label ("Select Multiple");
6937       g_signal_connect (button, "clicked",
6938                         G_CALLBACK (select_multiple),
6939                         window);
6940       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6941                           button, FALSE, FALSE, 0);
6942       gtk_widget_show (button);
6943     }
6944   
6945   if (!GTK_WIDGET_VISIBLE (window))
6946     gtk_widget_show (window);
6947   else
6948     gtk_widget_destroy (window);
6949 }
6950
6951 void
6952 flipping_toggled_cb (GtkWidget *widget, gpointer data)
6953 {
6954   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6955   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
6956
6957   gtk_widget_set_default_direction (new_direction);
6958 }
6959
6960 void
6961 create_flipping (GtkWidget *widget)
6962 {
6963   static GtkWidget *window = NULL;
6964   GtkWidget *check_button, *button;
6965
6966   if (!window)
6967     {
6968       window = gtk_dialog_new ();
6969
6970       gtk_window_set_screen (GTK_WINDOW (window),
6971                              gtk_widget_get_screen (widget));
6972
6973       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6974                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6975                           &window);
6976
6977       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
6978
6979       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
6980       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
6981                           check_button, TRUE, TRUE, 0);
6982
6983       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
6984         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
6985
6986       gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6987                           GTK_SIGNAL_FUNC (flipping_toggled_cb), FALSE);
6988
6989       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
6990       
6991       button = gtk_button_new_with_label ("Close");
6992       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6993                                  GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window));
6994       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6995                           button, TRUE, TRUE, 0);
6996     }
6997   
6998   if (!GTK_WIDGET_VISIBLE (window))
6999     gtk_widget_show_all (window);
7000   else
7001     gtk_widget_destroy (window);
7002 }
7003
7004 /*
7005  * Focus test
7006  */
7007
7008 static GtkWidget*
7009 make_focus_table (GList **list)
7010 {
7011   GtkWidget *table;
7012   gint i, j;
7013   
7014   table = gtk_table_new (5, 5, FALSE);
7015
7016   i = 0;
7017   j = 0;
7018
7019   while (i < 5)
7020     {
7021       j = 0;
7022       while (j < 5)
7023         {
7024           GtkWidget *widget;
7025           
7026           if ((i + j) % 2)
7027             widget = gtk_entry_new ();
7028           else
7029             widget = gtk_button_new_with_label ("Foo");
7030
7031           *list = g_list_prepend (*list, widget);
7032           
7033           gtk_table_attach (GTK_TABLE (table),
7034                             widget,
7035                             i, i + 1,
7036                             j, j + 1,
7037                             GTK_EXPAND | GTK_FILL,
7038                             GTK_EXPAND | GTK_FILL,
7039                             5, 5);
7040           
7041           ++j;
7042         }
7043
7044       ++i;
7045     }
7046
7047   *list = g_list_reverse (*list);
7048   
7049   return table;
7050 }
7051
7052 static void
7053 create_focus (GtkWidget *widget)
7054 {
7055   static GtkWidget *window = NULL;
7056   
7057   if (!window)
7058     {
7059       GtkWidget *table;
7060       GtkWidget *frame;
7061       GList *list = NULL;
7062       
7063       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
7064                                             NULL, 0,
7065                                             GTK_STOCK_CLOSE,
7066                                             GTK_RESPONSE_NONE,
7067                                             NULL);
7068
7069       gtk_window_set_screen (GTK_WINDOW (window),
7070                              gtk_widget_get_screen (widget));
7071
7072       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7073                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7074                           &window);
7075
7076       gtk_signal_connect (GTK_OBJECT (window), "response",
7077                           GTK_SIGNAL_FUNC (gtk_widget_destroy),
7078                           NULL);
7079       
7080       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
7081
7082       frame = gtk_frame_new ("Weird tab focus chain");
7083
7084       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7085                           frame, TRUE, TRUE, 0);
7086       
7087       table = make_focus_table (&list);
7088
7089       gtk_container_add (GTK_CONTAINER (frame), table);
7090
7091       gtk_container_set_focus_chain (GTK_CONTAINER (table),
7092                                      list);
7093
7094       g_list_free (list);
7095       
7096       frame = gtk_frame_new ("Default tab focus chain");
7097
7098       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7099                           frame, TRUE, TRUE, 0);
7100
7101       list = NULL;
7102       table = make_focus_table (&list);
7103
7104       g_list_free (list);
7105       
7106       gtk_container_add (GTK_CONTAINER (frame), table);      
7107     }
7108   
7109   if (!GTK_WIDGET_VISIBLE (window))
7110     gtk_widget_show_all (window);
7111   else
7112     gtk_widget_destroy (window);
7113 }
7114
7115 /*
7116  * GtkFontSelection
7117  */
7118
7119 void
7120 font_selection_ok (GtkWidget              *w,
7121                    GtkFontSelectionDialog *fs)
7122 {
7123   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
7124
7125   g_print ("%s\n", s);
7126   g_free (s);
7127   gtk_widget_destroy (GTK_WIDGET (fs));
7128 }
7129
7130 void
7131 create_font_selection (GtkWidget *widget)
7132 {
7133   static GtkWidget *window = NULL;
7134
7135   if (!window)
7136     {
7137       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
7138       
7139       gtk_window_set_screen (GTK_WINDOW (window),
7140                              gtk_widget_get_screen (widget));
7141
7142       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
7143
7144       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7145                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7146                           &window);
7147
7148       gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
7149                           "clicked", GTK_SIGNAL_FUNC(font_selection_ok),
7150                           GTK_FONT_SELECTION_DIALOG (window));
7151       gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
7152                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
7153                                  GTK_OBJECT (window));
7154     }
7155   
7156   if (!GTK_WIDGET_VISIBLE (window))
7157     gtk_widget_show (window);
7158   else
7159     gtk_widget_destroy (window);
7160 }
7161
7162 /*
7163  * GtkDialog
7164  */
7165
7166 static GtkWidget *dialog_window = NULL;
7167
7168 static void
7169 label_toggle (GtkWidget  *widget,
7170               GtkWidget **label)
7171 {
7172   if (!(*label))
7173     {
7174       *label = gtk_label_new ("Dialog Test");
7175       gtk_signal_connect (GTK_OBJECT (*label),
7176                           "destroy",
7177                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7178                           label);
7179       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
7180       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7181                           *label, TRUE, TRUE, 0);
7182       gtk_widget_show (*label);
7183     }
7184   else
7185     gtk_widget_destroy (*label);
7186 }
7187
7188 #define RESPONSE_TOGGLE_SEPARATOR 1
7189
7190 static void
7191 print_response (GtkWidget *dialog,
7192                 gint       response_id,
7193                 gpointer   data)
7194 {
7195   g_print ("response signal received (%d)\n", response_id);
7196
7197   if (response_id == RESPONSE_TOGGLE_SEPARATOR)
7198     {
7199       gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
7200                                     !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
7201     }
7202 }
7203
7204 static void
7205 create_dialog (GtkWidget *widget)
7206 {
7207   static GtkWidget *label;
7208   GtkWidget *button;
7209
7210   if (!dialog_window)
7211     {
7212       /* This is a terrible example; it's much simpler to create
7213        * dialogs than this. Don't use testgtk for example code,
7214        * use gtk-demo ;-)
7215        */
7216       
7217       dialog_window = gtk_dialog_new ();
7218       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7219                              gtk_widget_get_screen (widget));
7220
7221       gtk_signal_connect (GTK_OBJECT (dialog_window),
7222                           "response",
7223                           GTK_SIGNAL_FUNC (print_response),
7224                           NULL);
7225       
7226       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
7227                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7228                           &dialog_window);
7229
7230       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
7231       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7232
7233       button = gtk_button_new_with_label ("OK");
7234       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7235       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
7236                           button, TRUE, TRUE, 0);
7237       gtk_widget_grab_default (button);
7238       gtk_widget_show (button);
7239
7240       button = gtk_button_new_with_label ("Toggle");
7241       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7242                           GTK_SIGNAL_FUNC (label_toggle),
7243                           &label);
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_show (button);
7248
7249       label = NULL;
7250       
7251       button = gtk_button_new_with_label ("Separator");
7252
7253       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7254
7255       gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
7256                                     button,
7257                                     RESPONSE_TOGGLE_SEPARATOR);
7258       gtk_widget_show (button);
7259     }
7260
7261   if (!GTK_WIDGET_VISIBLE (dialog_window))
7262     gtk_widget_show (dialog_window);
7263   else
7264     gtk_widget_destroy (dialog_window);
7265 }
7266
7267 /* Display & Screen test 
7268  */
7269
7270 typedef struct 
7271
7272   GtkEntry *entry;
7273   GtkWidget *radio_dpy;
7274   GtkWidget *toplevel; 
7275   GtkWidget *dialog_window;
7276   GList *valid_display_list;
7277 } ScreenDisplaySelection;
7278
7279 static gint
7280 display_name_cmp (gconstpointer a,
7281                   gconstpointer b)
7282 {
7283   return g_ascii_strcasecmp (a,b);
7284 }
7285
7286 static void
7287 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
7288 {
7289   char *display_name;
7290   GdkDisplay *display = gtk_widget_get_display (widget);
7291   GtkWidget *dialog;
7292   GdkScreen *new_screen = NULL;
7293   GdkScreen *current_screen = gtk_widget_get_screen (widget);
7294   
7295   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
7296     {
7297       display_name = g_strdup (gtk_entry_get_text (data->entry));
7298       display = gdk_display_open (display_name);
7299       
7300       if (!display)
7301         {
7302           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
7303                                            GTK_DIALOG_DESTROY_WITH_PARENT,
7304                                            GTK_MESSAGE_ERROR,
7305                                            GTK_BUTTONS_OK,
7306                                            "The display :\n%s\ncannot be opened",
7307                                            display_name);
7308           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
7309           gtk_widget_show (dialog);
7310           g_signal_connect (G_OBJECT (dialog), "response",
7311                             G_CALLBACK (gtk_widget_destroy),
7312                             NULL);
7313         }
7314       else
7315         {
7316           if (!g_list_find_custom (data->valid_display_list, 
7317                                    display_name,
7318                                    display_name_cmp))
7319             data->valid_display_list = g_list_append (data->valid_display_list,
7320                                                       display_name);
7321           
7322           new_screen = gdk_display_get_default_screen (display);
7323         }
7324     }
7325   else
7326     {
7327       gint number_of_screens = gdk_display_get_n_screens (display);
7328       gint screen_num = gdk_screen_get_number (current_screen);
7329       if ((screen_num +1) < number_of_screens)
7330         new_screen = gdk_display_get_screen (display, screen_num + 1);
7331       else
7332         new_screen = gdk_display_get_screen (display, 0);
7333     }
7334   
7335   if (new_screen) 
7336     {
7337       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
7338       gtk_widget_destroy (data->dialog_window);
7339     }
7340 }
7341
7342 void
7343 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
7344 {
7345   gtk_widget_destroy (data);
7346 }
7347
7348 void
7349 create_display_screen (GtkWidget *widget)
7350 {
7351   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
7352   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
7353   GtkWidget *bbox;
7354   ScreenDisplaySelection *scr_dpy_data;
7355   GdkScreen *screen = gtk_widget_get_screen (widget);
7356   static GList *valid_display_list = NULL;
7357   
7358   GdkDisplay *display = gdk_screen_get_display (screen);
7359
7360   window = gtk_widget_new (gtk_window_get_type (),
7361                            "screen", screen,
7362                            "user_data", NULL,
7363                            "type", GTK_WINDOW_TOPLEVEL,
7364                            "title",
7365                            "Screen or Display selection",
7366                            "border_width", 10, NULL);
7367   g_signal_connect (G_OBJECT (window), "destroy", 
7368                     G_CALLBACK (gtk_widget_destroy), NULL);
7369
7370   vbox = gtk_vbox_new (FALSE, 3);
7371   gtk_container_add (GTK_CONTAINER (window), vbox);
7372   
7373   frame = gtk_frame_new ("Select screen or display");
7374   gtk_container_add (GTK_CONTAINER (vbox), frame);
7375   
7376   table = gtk_table_new (2, 2, TRUE);
7377   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
7378   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
7379
7380   gtk_container_add (GTK_CONTAINER (frame), table);
7381
7382   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
7383   if (gdk_display_get_n_screens(display) > 1)
7384     radio_scr = gtk_radio_button_new_with_label 
7385     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
7386   else
7387     {    
7388       radio_scr = gtk_radio_button_new_with_label 
7389         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
7390          "only one screen on the current display");
7391       gtk_widget_set_sensitive (radio_scr, FALSE);
7392     }
7393   combo_dpy = gtk_combo_new ();
7394   if (!valid_display_list)
7395     valid_display_list = g_list_append (valid_display_list, "diabolo:0.0");
7396     
7397   gtk_combo_set_popdown_strings (GTK_COMBO (combo_dpy), valid_display_list);
7398     
7399   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_dpy)->entry), 
7400                       "<hostname>:<X Server Num>.<Screen Num>");
7401
7402   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
7403   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
7404   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
7405
7406   bbox = gtk_hbutton_box_new ();
7407   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
7408   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
7409   
7410   gtk_container_add (GTK_CONTAINER (vbox), bbox);
7411
7412   gtk_container_add (GTK_CONTAINER (bbox), applyb);
7413   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
7414
7415   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
7416
7417   scr_dpy_data->entry = GTK_ENTRY (GTK_COMBO (combo_dpy)->entry);
7418   scr_dpy_data->radio_dpy = radio_dpy;
7419   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
7420   scr_dpy_data->dialog_window = window;
7421   scr_dpy_data->valid_display_list = valid_display_list;
7422
7423   g_signal_connect (G_OBJECT (cancelb), "clicked", 
7424                     G_CALLBACK (screen_display_destroy_diag), G_OBJECT (window));
7425   g_signal_connect (G_OBJECT (applyb), "clicked", 
7426                     G_CALLBACK (screen_display_check), scr_dpy_data);
7427   gtk_widget_show_all (window);
7428 }
7429
7430 /* Event Watcher
7431  */
7432 static gboolean event_watcher_enter_id = 0;
7433 static gboolean event_watcher_leave_id = 0;
7434
7435 static gboolean
7436 event_watcher (GSignalInvocationHint *ihint,
7437                guint                  n_param_values,
7438                const GValue          *param_values,
7439                gpointer               data)
7440 {
7441   g_print ("Watch: \"%s\" emitted for %s\n",
7442            gtk_signal_name (ihint->signal_id),
7443            gtk_type_name (GTK_OBJECT_TYPE (g_value_get_object (param_values + 0))));
7444
7445   return TRUE;
7446 }
7447
7448 static void
7449 event_watcher_down (void)
7450 {
7451   if (event_watcher_enter_id)
7452     {
7453       guint signal_id;
7454
7455       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7456       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
7457       event_watcher_enter_id = 0;
7458       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7459       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
7460       event_watcher_leave_id = 0;
7461     }
7462 }
7463
7464 static void
7465 event_watcher_toggle (void)
7466 {
7467   if (event_watcher_enter_id)
7468     event_watcher_down ();
7469   else
7470     {
7471       guint signal_id;
7472
7473       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7474       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7475       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7476       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7477     }
7478 }
7479
7480 static void
7481 create_event_watcher (GtkWidget *widget)
7482 {
7483   GtkWidget *button;
7484
7485   if (!dialog_window)
7486     {
7487       dialog_window = gtk_dialog_new ();
7488       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7489                              gtk_widget_get_screen (widget));
7490
7491       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
7492                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7493                           &dialog_window);
7494       gtk_signal_connect (GTK_OBJECT (dialog_window),
7495                           "destroy",
7496                           GTK_SIGNAL_FUNC (event_watcher_down),
7497                           NULL);
7498
7499       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
7500       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7501       gtk_widget_set_usize (dialog_window, 200, 110);
7502
7503       button = gtk_toggle_button_new_with_label ("Activate Watch");
7504       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7505                           GTK_SIGNAL_FUNC (event_watcher_toggle),
7506                           NULL);
7507       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
7508       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7509                           button, TRUE, TRUE, 0);
7510       gtk_widget_show (button);
7511
7512       button = gtk_button_new_with_label ("Close");
7513       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7514                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7515                                  (GtkObject*) dialog_window);
7516       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7517       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7518                           button, TRUE, TRUE, 0);
7519       gtk_widget_grab_default (button);
7520       gtk_widget_show (button);
7521     }
7522
7523   if (!GTK_WIDGET_VISIBLE (dialog_window))
7524     gtk_widget_show (dialog_window);
7525   else
7526     gtk_widget_destroy (dialog_window);
7527 }
7528
7529 /*
7530  * GtkRange
7531  */
7532
7533 static gchar*
7534 reformat_value (GtkScale *scale,
7535                 gdouble   value)
7536 {
7537   return g_strdup_printf ("-->%0.*g<--",
7538                           gtk_scale_get_digits (scale), value);
7539 }
7540
7541 static void
7542 create_range_controls (GtkWidget *widget)
7543 {
7544   static GtkWidget *window = NULL;
7545   GtkWidget *box1;
7546   GtkWidget *box2;
7547   GtkWidget *button;
7548   GtkWidget *scrollbar;
7549   GtkWidget *scale;
7550   GtkWidget *separator;
7551   GtkObject *adjustment;
7552   GtkWidget *hbox;
7553
7554   if (!window)
7555     {
7556       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7557
7558       gtk_window_set_screen (GTK_WINDOW (window),
7559                              gtk_widget_get_screen (widget));
7560
7561       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7562                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7563                           &window);
7564
7565       gtk_window_set_title (GTK_WINDOW (window), "range controls");
7566       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7567
7568
7569       box1 = gtk_vbox_new (FALSE, 0);
7570       gtk_container_add (GTK_CONTAINER (window), box1);
7571       gtk_widget_show (box1);
7572
7573
7574       box2 = gtk_vbox_new (FALSE, 10);
7575       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7576       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7577       gtk_widget_show (box2);
7578
7579
7580       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
7581
7582       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7583       gtk_widget_set_usize (GTK_WIDGET (scale), 150, -1);
7584       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
7585       gtk_scale_set_digits (GTK_SCALE (scale), 1);
7586       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7587       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7588       gtk_widget_show (scale);
7589
7590       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
7591       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
7592                                    GTK_UPDATE_CONTINUOUS);
7593       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
7594       gtk_widget_show (scrollbar);
7595
7596       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7597       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7598       gtk_signal_connect (GTK_OBJECT (scale),
7599                           "format_value",
7600                           GTK_SIGNAL_FUNC (reformat_value),
7601                           NULL);
7602       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7603       gtk_widget_show (scale);
7604       
7605       hbox = gtk_hbox_new (FALSE, 0);
7606
7607       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7608       gtk_widget_set_usize (scale, -1, 200);
7609       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7610       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7611       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7612       gtk_widget_show (scale);
7613
7614       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7615       gtk_widget_set_usize (scale, -1, 200);
7616       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7617       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7618       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
7619       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7620       gtk_widget_show (scale);
7621
7622       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7623       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7624       gtk_signal_connect (GTK_OBJECT (scale),
7625                           "format_value",
7626                           GTK_SIGNAL_FUNC (reformat_value),
7627                           NULL);
7628       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7629       gtk_widget_show (scale);
7630
7631       
7632       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
7633       gtk_widget_show (hbox);
7634       
7635       separator = gtk_hseparator_new ();
7636       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7637       gtk_widget_show (separator);
7638
7639
7640       box2 = gtk_vbox_new (FALSE, 10);
7641       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7642       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7643       gtk_widget_show (box2);
7644
7645
7646       button = gtk_button_new_with_label ("close");
7647       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7648                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7649                                  GTK_OBJECT (window));
7650       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7651       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7652       gtk_widget_grab_default (button);
7653       gtk_widget_show (button);
7654     }
7655
7656   if (!GTK_WIDGET_VISIBLE (window))
7657     gtk_widget_show (window);
7658   else
7659     gtk_widget_destroy (window);
7660 }
7661
7662 /*
7663  * GtkRulers
7664  */
7665
7666 void
7667 create_rulers (GtkWidget *widget)
7668 {
7669   static GtkWidget *window = NULL;
7670   GtkWidget *table;
7671   GtkWidget *ruler;
7672
7673   if (!window)
7674     {
7675       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7676
7677       gtk_window_set_screen (GTK_WINDOW (window),
7678                              gtk_widget_get_screen (widget));
7679
7680       gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
7681
7682       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7683                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7684                           &window);
7685
7686       gtk_window_set_title (GTK_WINDOW (window), "rulers");
7687       gtk_widget_set_usize (window, 300, 300);
7688       gtk_widget_set_events (window, 
7689                              GDK_POINTER_MOTION_MASK 
7690                              | GDK_POINTER_MOTION_HINT_MASK);
7691       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7692
7693       table = gtk_table_new (2, 2, FALSE);
7694       gtk_container_add (GTK_CONTAINER (window), table);
7695       gtk_widget_show (table);
7696
7697       ruler = gtk_hruler_new ();
7698       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
7699       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
7700
7701       gtk_signal_connect_object (GTK_OBJECT (window), 
7702                                  "motion_notify_event",
7703                                  GTK_SIGNAL_FUNC (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7704                                  GTK_OBJECT (ruler));
7705       
7706       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
7707                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
7708       gtk_widget_show (ruler);
7709
7710
7711       ruler = gtk_vruler_new ();
7712       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
7713
7714       gtk_signal_connect_object (GTK_OBJECT (window), 
7715                                  "motion_notify_event",
7716                                  GTK_SIGNAL_FUNC (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7717                                  GTK_OBJECT (ruler));
7718       
7719       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
7720                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
7721       gtk_widget_show (ruler);
7722     }
7723
7724   if (!GTK_WIDGET_VISIBLE (window))
7725     gtk_widget_show (window);
7726   else
7727     gtk_widget_destroy (window);
7728 }
7729
7730 static void
7731 text_toggle_editable (GtkWidget *checkbutton,
7732                        GtkWidget *text)
7733 {
7734    gtk_text_set_editable(GTK_TEXT(text),
7735                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7736 }
7737
7738 static void
7739 text_toggle_word_wrap (GtkWidget *checkbutton,
7740                        GtkWidget *text)
7741 {
7742    gtk_text_set_word_wrap(GTK_TEXT(text),
7743                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7744 }
7745
7746 struct {
7747   GdkColor color;
7748   gchar *name;
7749 } text_colors[] = {
7750  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
7751  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
7752  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
7753  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
7754  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
7755  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
7756  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
7757  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
7758 };
7759
7760 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
7761
7762 /*
7763  * GtkText
7764  */
7765 void
7766 text_insert_random (GtkWidget *w, GtkText *text)
7767 {
7768   int i;
7769   char c;
7770    for (i=0; i<10; i++)
7771     {
7772       c = 'A' + rand() % ('Z' - 'A');
7773       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
7774       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
7775     }
7776 }
7777
7778 void
7779 create_text (GtkWidget *widget)
7780 {
7781   int i, j;
7782
7783   static GtkWidget *window = NULL;
7784   GtkWidget *box1;
7785   GtkWidget *box2;
7786   GtkWidget *hbox;
7787   GtkWidget *button;
7788   GtkWidget *check;
7789   GtkWidget *separator;
7790   GtkWidget *scrolled_window;
7791   GtkWidget *text;
7792
7793   FILE *infile;
7794
7795   if (!window)
7796     {
7797       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7798       gtk_window_set_screen (GTK_WINDOW (window),
7799                              gtk_widget_get_screen (widget));
7800
7801       gtk_widget_set_name (window, "text window");
7802       gtk_widget_set_usize (window, 500, 500);
7803       gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
7804
7805       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7806                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7807                           &window);
7808
7809       gtk_window_set_title (GTK_WINDOW (window), "test");
7810       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7811
7812
7813       box1 = gtk_vbox_new (FALSE, 0);
7814       gtk_container_add (GTK_CONTAINER (window), box1);
7815       gtk_widget_show (box1);
7816
7817
7818       box2 = gtk_vbox_new (FALSE, 10);
7819       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7820       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7821       gtk_widget_show (box2);
7822
7823
7824       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
7825       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
7826       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
7827                                       GTK_POLICY_NEVER,
7828                                       GTK_POLICY_ALWAYS);
7829       gtk_widget_show (scrolled_window);
7830
7831       text = gtk_text_new (NULL, NULL);
7832       gtk_text_set_editable (GTK_TEXT (text), TRUE);
7833       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
7834       gtk_widget_grab_focus (text);
7835       gtk_widget_show (text);
7836
7837
7838       gtk_text_freeze (GTK_TEXT (text));
7839
7840       for (i=0; i<ntext_colors; i++)
7841         {
7842           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, 
7843                            text_colors[i].name, -1);
7844           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\t", -1);
7845
7846           for (j=0; j<ntext_colors; j++)
7847             {
7848               gtk_text_insert (GTK_TEXT (text), NULL,
7849                                &text_colors[j].color, &text_colors[i].color,
7850                                "XYZ", -1);
7851             }
7852           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
7853         }
7854
7855       infile = fopen("testgtk.c", "r");
7856       
7857       if (infile)
7858         {
7859           char *buffer;
7860           int nbytes_read, nbytes_alloc;
7861           
7862           nbytes_read = 0;
7863           nbytes_alloc = 1024;
7864           buffer = g_new (char, nbytes_alloc);
7865           while (1)
7866             {
7867               int len;
7868               if (nbytes_alloc < nbytes_read + 1024)
7869                 {
7870                   nbytes_alloc *= 2;
7871                   buffer = g_realloc (buffer, nbytes_alloc);
7872                 }
7873               len = fread (buffer + nbytes_read, 1, 1024, infile);
7874               nbytes_read += len;
7875               if (len < 1024)
7876                 break;
7877             }
7878           
7879           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
7880                            NULL, buffer, nbytes_read);
7881           g_free(buffer);
7882           fclose (infile);
7883         }
7884       
7885       gtk_text_thaw (GTK_TEXT (text));
7886
7887       hbox = gtk_hbutton_box_new ();
7888       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
7889       gtk_widget_show (hbox);
7890
7891       check = gtk_check_button_new_with_label("Editable");
7892       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
7893       gtk_signal_connect (GTK_OBJECT(check), "toggled",
7894                           GTK_SIGNAL_FUNC(text_toggle_editable), text);
7895       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
7896       gtk_widget_show (check);
7897
7898       check = gtk_check_button_new_with_label("Wrap Words");
7899       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
7900       gtk_signal_connect (GTK_OBJECT(check), "toggled",
7901                           GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
7902       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
7903       gtk_widget_show (check);
7904
7905       separator = gtk_hseparator_new ();
7906       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7907       gtk_widget_show (separator);
7908
7909
7910       box2 = gtk_vbox_new (FALSE, 10);
7911       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7912       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7913       gtk_widget_show (box2);
7914
7915
7916       button = gtk_button_new_with_label ("insert random");
7917       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7918                           GTK_SIGNAL_FUNC(text_insert_random),
7919                           GTK_TEXT (text));
7920       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7921       gtk_widget_show (button);
7922
7923       button = gtk_button_new_with_label ("close");
7924       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7925                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7926                                  GTK_OBJECT (window));
7927       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7928       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7929       gtk_widget_grab_default (button);
7930       gtk_widget_show (button);
7931     }
7932
7933   if (!GTK_WIDGET_VISIBLE (window))
7934     gtk_widget_show (window);
7935   else
7936     gtk_widget_destroy (window);
7937 }
7938
7939 /*
7940  * GtkNotebook
7941  */
7942
7943 GdkPixbuf *book_open;
7944 GdkPixbuf *book_closed;
7945 GtkWidget *sample_notebook;
7946
7947 static void
7948 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
7949 {
7950   GtkWidget *page_widget;
7951   GtkWidget *pixwid;
7952
7953   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
7954
7955   pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
7956   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
7957   
7958   pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
7959   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
7960 }
7961
7962 static void
7963 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
7964 {
7965   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
7966   gint old_page_num = gtk_notebook_get_current_page (notebook);
7967  
7968   if (page_num == old_page_num)
7969     return;
7970
7971   set_page_image (notebook, page_num, book_open);
7972
7973   if (old_page_num != -1)
7974     set_page_image (notebook, old_page_num, book_closed);
7975 }
7976
7977 static void
7978 tab_fill (GtkToggleButton *button, GtkWidget *child)
7979 {
7980   gboolean expand;
7981   GtkPackType pack_type;
7982
7983   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7984                                         &expand, NULL, &pack_type);
7985   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7986                                       expand, button->active, pack_type);
7987 }
7988
7989 static void
7990 tab_expand (GtkToggleButton *button, GtkWidget *child)
7991 {
7992   gboolean fill;
7993   GtkPackType pack_type;
7994
7995   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7996                                         NULL, &fill, &pack_type);
7997   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7998                                       button->active, fill, pack_type);
7999 }
8000
8001 static void
8002 tab_pack (GtkToggleButton *button, GtkWidget *child)
8003           
8004
8005   gboolean expand;
8006   gboolean fill;
8007
8008   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8009                                         &expand, &fill, NULL);
8010   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8011                                       expand, fill, button->active);
8012 }
8013
8014 static void
8015 create_pages (GtkNotebook *notebook, gint start, gint end)
8016 {
8017   GtkWidget *child = NULL;
8018   GtkWidget *button;
8019   GtkWidget *label;
8020   GtkWidget *hbox;
8021   GtkWidget *vbox;
8022   GtkWidget *label_box;
8023   GtkWidget *menu_box;
8024   GtkWidget *pixwid;
8025   gint i;
8026   char buffer[32];
8027   char accel_buffer[32];
8028
8029   for (i = start; i <= end; i++)
8030     {
8031       sprintf (buffer, "Page %d", i);
8032       sprintf (accel_buffer, "Page _%d", i);
8033
8034       child = gtk_frame_new (buffer);
8035       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
8036
8037       vbox = gtk_vbox_new (TRUE,0);
8038       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8039       gtk_container_add (GTK_CONTAINER (child), vbox);
8040
8041       hbox = gtk_hbox_new (TRUE,0);
8042       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
8043
8044       button = gtk_check_button_new_with_label ("Fill Tab");
8045       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8046       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8047       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8048                           GTK_SIGNAL_FUNC (tab_fill), child);
8049
8050       button = gtk_check_button_new_with_label ("Expand Tab");
8051       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8052       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8053       GTK_SIGNAL_FUNC (tab_expand), child);
8054
8055       button = gtk_check_button_new_with_label ("Pack end");
8056       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8057       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8058                           GTK_SIGNAL_FUNC (tab_pack), child);
8059
8060       button = gtk_button_new_with_label ("Hide Page");
8061       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
8062       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8063                                  GTK_SIGNAL_FUNC (gtk_widget_hide),
8064                                  GTK_OBJECT (child));
8065
8066       gtk_widget_show_all (child);
8067
8068       label_box = gtk_hbox_new (FALSE, 0);
8069       pixwid = gtk_image_new_from_pixbuf (book_closed);
8070       gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
8071                            
8072       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
8073       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8074       label = gtk_label_new_with_mnemonic (accel_buffer);
8075       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
8076       gtk_widget_show_all (label_box);
8077       
8078                                        
8079       menu_box = gtk_hbox_new (FALSE, 0);
8080       pixwid = gtk_image_new_from_pixbuf (book_closed);
8081       gtk_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
8082       
8083       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
8084       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8085       label = gtk_label_new (buffer);
8086       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
8087       gtk_widget_show_all (menu_box);
8088
8089       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
8090     }
8091 }
8092
8093 static void
8094 rotate_notebook (GtkButton   *button,
8095                  GtkNotebook *notebook)
8096 {
8097   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
8098 }
8099
8100 static void
8101 show_all_pages (GtkButton   *button,
8102                 GtkNotebook *notebook)
8103 {  
8104   gtk_container_foreach (GTK_CONTAINER (notebook),
8105                          (GtkCallback) gtk_widget_show, NULL);
8106 }
8107
8108 static void
8109 notebook_type_changed (GtkWidget *optionmenu,
8110                        gpointer   data)
8111 {
8112   GtkNotebook *notebook;
8113   gint i, c;
8114
8115   enum {
8116     STANDARD,
8117     NOTABS,
8118     BORDERLESS,
8119     SCROLLABLE
8120   };
8121
8122   notebook = GTK_NOTEBOOK (data);
8123
8124   c = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
8125
8126   switch (c)
8127     {
8128     case STANDARD:
8129       /* standard notebook */
8130       gtk_notebook_set_show_tabs (notebook, TRUE);
8131       gtk_notebook_set_show_border (notebook, TRUE);
8132       gtk_notebook_set_scrollable (notebook, FALSE);
8133       break;
8134
8135     case NOTABS:
8136       /* notabs notebook */
8137       gtk_notebook_set_show_tabs (notebook, FALSE);
8138       gtk_notebook_set_show_border (notebook, TRUE);
8139       break;
8140
8141     case BORDERLESS:
8142       /* borderless */
8143       gtk_notebook_set_show_tabs (notebook, FALSE);
8144       gtk_notebook_set_show_border (notebook, FALSE);
8145       break;
8146
8147     case SCROLLABLE:  
8148       /* scrollable */
8149       gtk_notebook_set_show_tabs (notebook, TRUE);
8150       gtk_notebook_set_show_border (notebook, TRUE);
8151       gtk_notebook_set_scrollable (notebook, TRUE);
8152       if (g_list_length (notebook->children) == 5)
8153         create_pages (notebook, 6, 15);
8154       
8155       return;
8156       break;
8157     }
8158   
8159   if (g_list_length (notebook->children) == 15)
8160     for (i = 0; i < 10; i++)
8161       gtk_notebook_remove_page (notebook, 5);
8162 }
8163
8164 static void
8165 notebook_popup (GtkToggleButton *button,
8166                 GtkNotebook     *notebook)
8167 {
8168   if (button->active)
8169     gtk_notebook_popup_enable (notebook);
8170   else
8171     gtk_notebook_popup_disable (notebook);
8172 }
8173
8174 static void
8175 notebook_homogeneous (GtkToggleButton *button,
8176                       GtkNotebook     *notebook)
8177 {
8178   gtk_notebook_set_homogeneous_tabs (notebook, button->active);
8179 }
8180
8181 static void
8182 create_notebook (GtkWidget *widget)
8183 {
8184   static GtkWidget *window = NULL;
8185   GtkWidget *box1;
8186   GtkWidget *box2;
8187   GtkWidget *button;
8188   GtkWidget *separator;
8189   GtkWidget *omenu;
8190   GtkWidget *label;
8191
8192   static gchar *items[] =
8193   {
8194     "Standard",
8195     "No tabs",
8196     "Borderless",
8197     "Scrollable"
8198   };
8199   
8200   if (!window)
8201     {
8202       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8203       gtk_window_set_screen (GTK_WINDOW (window),
8204                              gtk_widget_get_screen (widget));
8205
8206       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8207                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8208                           &window);
8209
8210       gtk_window_set_title (GTK_WINDOW (window), "notebook");
8211       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8212
8213       box1 = gtk_vbox_new (FALSE, 0);
8214       gtk_container_add (GTK_CONTAINER (window), box1);
8215
8216       sample_notebook = gtk_notebook_new ();
8217       gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page",
8218                           GTK_SIGNAL_FUNC (page_switch), NULL);
8219       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
8220       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
8221       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
8222
8223       gtk_widget_realize (sample_notebook);
8224
8225       if (!book_open)
8226         book_open = gdk_pixbuf_new_from_xpm_data ((const char **)book_open_xpm);
8227                                                   
8228       if (!book_closed)
8229         book_closed = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
8230
8231       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
8232
8233       separator = gtk_hseparator_new ();
8234       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
8235       
8236       box2 = gtk_hbox_new (FALSE, 5);
8237       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8238       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8239
8240       button = gtk_check_button_new_with_label ("popup menu");
8241       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8242       gtk_signal_connect (GTK_OBJECT(button), "clicked",
8243                           GTK_SIGNAL_FUNC (notebook_popup),
8244                           GTK_OBJECT (sample_notebook));
8245
8246       button = gtk_check_button_new_with_label ("homogeneous tabs");
8247       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8248       gtk_signal_connect (GTK_OBJECT(button), "clicked",
8249                           GTK_SIGNAL_FUNC (notebook_homogeneous),
8250                           GTK_OBJECT (sample_notebook));
8251
8252       box2 = gtk_hbox_new (FALSE, 5);
8253       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8254       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8255
8256       label = gtk_label_new ("Notebook Style :");
8257       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
8258
8259       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
8260                                  notebook_type_changed,
8261                                  sample_notebook);
8262       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
8263
8264       button = gtk_button_new_with_label ("Show all Pages");
8265       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
8266       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8267                           GTK_SIGNAL_FUNC (show_all_pages), sample_notebook);
8268
8269       box2 = gtk_hbox_new (TRUE, 10);
8270       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8271       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8272
8273       button = gtk_button_new_with_label ("prev");
8274       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8275                                  GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
8276                                  GTK_OBJECT (sample_notebook));
8277       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8278
8279       button = gtk_button_new_with_label ("next");
8280       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8281                                  GTK_SIGNAL_FUNC (gtk_notebook_next_page),
8282                                  GTK_OBJECT (sample_notebook));
8283       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8284
8285       button = gtk_button_new_with_label ("rotate");
8286       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8287                           GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook);
8288       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8289
8290       separator = gtk_hseparator_new ();
8291       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
8292
8293       button = gtk_button_new_with_label ("close");
8294       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
8295       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8296                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
8297                                  GTK_OBJECT (window));
8298       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
8299       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8300       gtk_widget_grab_default (button);
8301     }
8302
8303   if (!GTK_WIDGET_VISIBLE (window))
8304     gtk_widget_show_all (window);
8305   else
8306     gtk_widget_destroy (window);
8307 }
8308
8309 /*
8310  * GtkPanes
8311  */
8312
8313 void
8314 toggle_resize (GtkWidget *widget, GtkWidget *child)
8315 {
8316   GtkPaned *paned = GTK_PANED (child->parent);
8317   gboolean is_child1 = (child == paned->child1);
8318   gboolean resize, shrink;
8319
8320   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8321   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8322
8323   gtk_widget_ref (child);
8324   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8325   if (is_child1)
8326     gtk_paned_pack1 (paned, child, !resize, shrink);
8327   else
8328     gtk_paned_pack2 (paned, child, !resize, shrink);
8329   gtk_widget_unref (child);
8330 }
8331
8332 void
8333 toggle_shrink (GtkWidget *widget, GtkWidget *child)
8334 {
8335   GtkPaned *paned = GTK_PANED (child->parent);
8336   gboolean is_child1 = (child == paned->child1);
8337   gboolean resize, shrink;
8338
8339   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8340   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8341
8342   gtk_widget_ref (child);
8343   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8344   if (is_child1)
8345     gtk_paned_pack1 (paned, child, resize, !shrink);
8346   else
8347     gtk_paned_pack2 (paned, child, resize, !shrink);
8348   gtk_widget_unref (child);
8349 }
8350
8351 static void
8352 paned_props_clicked (GtkWidget *button,
8353                      GObject   *paned)
8354 {
8355   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
8356   
8357   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
8358 }
8359
8360 GtkWidget *
8361 create_pane_options (GtkPaned    *paned,
8362                      const gchar *frame_label,
8363                      const gchar *label1,
8364                      const gchar *label2)
8365 {
8366   GtkWidget *frame;
8367   GtkWidget *table;
8368   GtkWidget *label;
8369   GtkWidget *button;
8370   GtkWidget *check_button;
8371   
8372   frame = gtk_frame_new (frame_label);
8373   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
8374   
8375   table = gtk_table_new (4, 2, 4);
8376   gtk_container_add (GTK_CONTAINER (frame), table);
8377   
8378   label = gtk_label_new (label1);
8379   gtk_table_attach_defaults (GTK_TABLE (table), label,
8380                              0, 1, 0, 1);
8381   
8382   check_button = gtk_check_button_new_with_label ("Resize");
8383   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8384                              0, 1, 1, 2);
8385   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8386                       GTK_SIGNAL_FUNC (toggle_resize),
8387                       paned->child1);
8388   
8389   check_button = gtk_check_button_new_with_label ("Shrink");
8390   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8391                              0, 1, 2, 3);
8392   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8393                                TRUE);
8394   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8395                       GTK_SIGNAL_FUNC (toggle_shrink),
8396                       paned->child1);
8397   
8398   label = gtk_label_new (label2);
8399   gtk_table_attach_defaults (GTK_TABLE (table), label,
8400                              1, 2, 0, 1);
8401   
8402   check_button = gtk_check_button_new_with_label ("Resize");
8403   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8404                              1, 2, 1, 2);
8405   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8406                                TRUE);
8407   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8408                       GTK_SIGNAL_FUNC (toggle_resize),
8409                       paned->child2);
8410   
8411   check_button = gtk_check_button_new_with_label ("Shrink");
8412   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8413                              1, 2, 2, 3);
8414   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8415                                TRUE);
8416   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8417                       GTK_SIGNAL_FUNC (toggle_shrink),
8418                       paned->child2);
8419
8420   button = gtk_button_new_with_mnemonic ("_Properties");
8421   gtk_table_attach_defaults (GTK_TABLE (table), button,
8422                              0, 2, 3, 4);
8423   gtk_signal_connect (GTK_OBJECT (button), "clicked",
8424                       GTK_SIGNAL_FUNC (paned_props_clicked),
8425                       paned);
8426
8427   return frame;
8428 }
8429
8430 void
8431 create_panes (GtkWidget *widget)
8432 {
8433   static GtkWidget *window = NULL;
8434   GtkWidget *frame;
8435   GtkWidget *hpaned;
8436   GtkWidget *vpaned;
8437   GtkWidget *button;
8438   GtkWidget *vbox;
8439
8440   if (!window)
8441     {
8442       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8443
8444       gtk_window_set_screen (GTK_WINDOW (window),
8445                              gtk_widget_get_screen (widget));
8446       
8447       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8448                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8449                           &window);
8450
8451       gtk_window_set_title (GTK_WINDOW (window), "Panes");
8452       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8453
8454       vbox = gtk_vbox_new (FALSE, 0);
8455       gtk_container_add (GTK_CONTAINER (window), vbox);
8456       
8457       vpaned = gtk_vpaned_new ();
8458       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
8459       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
8460
8461       hpaned = gtk_hpaned_new ();
8462       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
8463
8464       frame = gtk_frame_new (NULL);
8465       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8466       gtk_widget_set_usize (frame, 60, 60);
8467       gtk_paned_add1 (GTK_PANED (hpaned), frame);
8468       
8469       button = gtk_button_new_with_label ("Hi there");
8470       gtk_container_add (GTK_CONTAINER(frame), button);
8471
8472       frame = gtk_frame_new (NULL);
8473       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8474       gtk_widget_set_usize (frame, 80, 60);
8475       gtk_paned_add2 (GTK_PANED (hpaned), frame);
8476
8477       frame = gtk_frame_new (NULL);
8478       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8479       gtk_widget_set_usize (frame, 60, 80);
8480       gtk_paned_add2 (GTK_PANED (vpaned), frame);
8481
8482       /* Now create toggle buttons to control sizing */
8483
8484       gtk_box_pack_start (GTK_BOX (vbox),
8485                           create_pane_options (GTK_PANED (hpaned),
8486                                                "Horizontal",
8487                                                "Left",
8488                                                "Right"),
8489                           FALSE, FALSE, 0);
8490
8491       gtk_box_pack_start (GTK_BOX (vbox),
8492                           create_pane_options (GTK_PANED (vpaned),
8493                                                "Vertical",
8494                                                "Top",
8495                                                "Bottom"),
8496                           FALSE, FALSE, 0);
8497
8498       gtk_widget_show_all (vbox);
8499     }
8500
8501   if (!GTK_WIDGET_VISIBLE (window))
8502     gtk_widget_show (window);
8503   else
8504     gtk_widget_destroy (window);
8505 }
8506
8507 /*
8508  * Paned keyboard navigation
8509  */
8510
8511 static GtkWidget*
8512 paned_keyboard_window1 (GtkWidget *widget)
8513 {
8514   GtkWidget *window1;
8515   GtkWidget *hpaned1;
8516   GtkWidget *frame1;
8517   GtkWidget *vbox1;
8518   GtkWidget *button7;
8519   GtkWidget *button8;
8520   GtkWidget *button9;
8521   GtkWidget *vpaned1;
8522   GtkWidget *frame2;
8523   GtkWidget *frame5;
8524   GtkWidget *hbox1;
8525   GtkWidget *button5;
8526   GtkWidget *button6;
8527   GtkWidget *frame3;
8528   GtkWidget *frame4;
8529   GtkWidget *table1;
8530   GtkWidget *button1;
8531   GtkWidget *button2;
8532   GtkWidget *button3;
8533   GtkWidget *button4;
8534
8535   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8536   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
8537   gtk_window_set_screen (GTK_WINDOW (window1), 
8538                          gtk_widget_get_screen (widget));
8539
8540   hpaned1 = gtk_hpaned_new ();
8541   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
8542
8543   frame1 = gtk_frame_new (NULL);
8544   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
8545   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
8546
8547   vbox1 = gtk_vbox_new (FALSE, 0);
8548   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
8549
8550   button7 = gtk_button_new_with_label ("button7");
8551   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
8552
8553   button8 = gtk_button_new_with_label ("button8");
8554   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
8555
8556   button9 = gtk_button_new_with_label ("button9");
8557   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
8558
8559   vpaned1 = gtk_vpaned_new ();
8560   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
8561
8562   frame2 = gtk_frame_new (NULL);
8563   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
8564   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
8565
8566   frame5 = gtk_frame_new (NULL);
8567   gtk_container_add (GTK_CONTAINER (frame2), frame5);
8568
8569   hbox1 = gtk_hbox_new (FALSE, 0);
8570   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
8571
8572   button5 = gtk_button_new_with_label ("button5");
8573   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
8574
8575   button6 = gtk_button_new_with_label ("button6");
8576   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
8577
8578   frame3 = gtk_frame_new (NULL);
8579   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
8580   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
8581
8582   frame4 = gtk_frame_new ("Buttons");
8583   gtk_container_add (GTK_CONTAINER (frame3), frame4);
8584   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
8585
8586   table1 = gtk_table_new (2, 2, FALSE);
8587   gtk_container_add (GTK_CONTAINER (frame4), table1);
8588   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
8589
8590   button1 = gtk_button_new_with_label ("button1");
8591   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
8592                     (GtkAttachOptions) (GTK_FILL),
8593                     (GtkAttachOptions) (0), 0, 0);
8594
8595   button2 = gtk_button_new_with_label ("button2");
8596   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
8597                     (GtkAttachOptions) (GTK_FILL),
8598                     (GtkAttachOptions) (0), 0, 0);
8599
8600   button3 = gtk_button_new_with_label ("button3");
8601   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
8602                     (GtkAttachOptions) (GTK_FILL),
8603                     (GtkAttachOptions) (0), 0, 0);
8604
8605   button4 = gtk_button_new_with_label ("button4");
8606   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
8607                     (GtkAttachOptions) (GTK_FILL),
8608                     (GtkAttachOptions) (0), 0, 0);
8609
8610   return window1;
8611 }
8612
8613 static GtkWidget*
8614 paned_keyboard_window2 (GtkWidget *widget)
8615 {
8616   GtkWidget *window2;
8617   GtkWidget *hpaned2;
8618   GtkWidget *frame6;
8619   GtkWidget *button13;
8620   GtkWidget *hbox2;
8621   GtkWidget *vpaned2;
8622   GtkWidget *frame7;
8623   GtkWidget *button12;
8624   GtkWidget *frame8;
8625   GtkWidget *button11;
8626   GtkWidget *button10;
8627
8628   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8629   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
8630
8631   gtk_window_set_screen (GTK_WINDOW (window2), 
8632                          gtk_widget_get_screen (widget));
8633
8634   hpaned2 = gtk_hpaned_new ();
8635   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
8636
8637   frame6 = gtk_frame_new (NULL);
8638   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
8639   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
8640
8641   button13 = gtk_button_new_with_label ("button13");
8642   gtk_container_add (GTK_CONTAINER (frame6), button13);
8643
8644   hbox2 = gtk_hbox_new (FALSE, 0);
8645   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
8646
8647   vpaned2 = gtk_vpaned_new ();
8648   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
8649
8650   frame7 = gtk_frame_new (NULL);
8651   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
8652   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
8653
8654   button12 = gtk_button_new_with_label ("button12");
8655   gtk_container_add (GTK_CONTAINER (frame7), button12);
8656
8657   frame8 = gtk_frame_new (NULL);
8658   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
8659   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
8660
8661   button11 = gtk_button_new_with_label ("button11");
8662   gtk_container_add (GTK_CONTAINER (frame8), button11);
8663
8664   button10 = gtk_button_new_with_label ("button10");
8665   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
8666
8667   return window2;
8668 }
8669
8670 static GtkWidget*
8671 paned_keyboard_window3 (GtkWidget *widget)
8672 {
8673   GtkWidget *window3;
8674   GtkWidget *vbox2;
8675   GtkWidget *label1;
8676   GtkWidget *hpaned3;
8677   GtkWidget *frame9;
8678   GtkWidget *button14;
8679   GtkWidget *hpaned4;
8680   GtkWidget *frame10;
8681   GtkWidget *button15;
8682   GtkWidget *hpaned5;
8683   GtkWidget *frame11;
8684   GtkWidget *button16;
8685   GtkWidget *frame12;
8686   GtkWidget *button17;
8687
8688   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8689   gtk_object_set_data (GTK_OBJECT (window3), "window3", window3);
8690   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
8691
8692   gtk_window_set_screen (GTK_WINDOW (window3), 
8693                          gtk_widget_get_screen (widget));
8694   
8695
8696   vbox2 = gtk_vbox_new (FALSE, 0);
8697   gtk_container_add (GTK_CONTAINER (window3), vbox2);
8698
8699   label1 = gtk_label_new ("Three panes nested inside each other");
8700   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
8701
8702   hpaned3 = gtk_hpaned_new ();
8703   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
8704
8705   frame9 = gtk_frame_new (NULL);
8706   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
8707   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
8708
8709   button14 = gtk_button_new_with_label ("button14");
8710   gtk_container_add (GTK_CONTAINER (frame9), button14);
8711
8712   hpaned4 = gtk_hpaned_new ();
8713   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
8714
8715   frame10 = gtk_frame_new (NULL);
8716   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
8717   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
8718
8719   button15 = gtk_button_new_with_label ("button15");
8720   gtk_container_add (GTK_CONTAINER (frame10), button15);
8721
8722   hpaned5 = gtk_hpaned_new ();
8723   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
8724
8725   frame11 = gtk_frame_new (NULL);
8726   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
8727   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
8728
8729   button16 = gtk_button_new_with_label ("button16");
8730   gtk_container_add (GTK_CONTAINER (frame11), button16);
8731
8732   frame12 = gtk_frame_new (NULL);
8733   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
8734   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
8735
8736   button17 = gtk_button_new_with_label ("button17");
8737   gtk_container_add (GTK_CONTAINER (frame12), button17);
8738
8739   return window3;
8740 }
8741
8742 static GtkWidget*
8743 paned_keyboard_window4 (GtkWidget *widget)
8744 {
8745   GtkWidget *window4;
8746   GtkWidget *vbox3;
8747   GtkWidget *label2;
8748   GtkWidget *hpaned6;
8749   GtkWidget *vpaned3;
8750   GtkWidget *button19;
8751   GtkWidget *button18;
8752   GtkWidget *hbox3;
8753   GtkWidget *vpaned4;
8754   GtkWidget *button21;
8755   GtkWidget *button20;
8756   GtkWidget *vpaned5;
8757   GtkWidget *button23;
8758   GtkWidget *button22;
8759   GtkWidget *vpaned6;
8760   GtkWidget *button25;
8761   GtkWidget *button24;
8762
8763   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8764   gtk_object_set_data (GTK_OBJECT (window4), "window4", window4);
8765   gtk_window_set_title (GTK_WINDOW (window4), "window4");
8766
8767   gtk_window_set_screen (GTK_WINDOW (window4), 
8768                          gtk_widget_get_screen (widget));
8769
8770   vbox3 = gtk_vbox_new (FALSE, 0);
8771   gtk_container_add (GTK_CONTAINER (window4), vbox3);
8772
8773   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
8774   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
8775   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
8776
8777   hpaned6 = gtk_hpaned_new ();
8778   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
8779
8780   vpaned3 = gtk_vpaned_new ();
8781   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
8782
8783   button19 = gtk_button_new_with_label ("button19");
8784   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
8785
8786   button18 = gtk_button_new_with_label ("button18");
8787   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
8788
8789   hbox3 = gtk_hbox_new (FALSE, 0);
8790   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
8791
8792   vpaned4 = gtk_vpaned_new ();
8793   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
8794
8795   button21 = gtk_button_new_with_label ("button21");
8796   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
8797
8798   button20 = gtk_button_new_with_label ("button20");
8799   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
8800
8801   vpaned5 = gtk_vpaned_new ();
8802   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
8803
8804   button23 = gtk_button_new_with_label ("button23");
8805   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
8806
8807   button22 = gtk_button_new_with_label ("button22");
8808   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
8809
8810   vpaned6 = gtk_vpaned_new ();
8811   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
8812
8813   button25 = gtk_button_new_with_label ("button25");
8814   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
8815
8816   button24 = gtk_button_new_with_label ("button24");
8817   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
8818
8819   return window4;
8820 }
8821
8822 static void
8823 create_paned_keyboard_navigation (GtkWidget *widget)
8824 {
8825   static GtkWidget *window1 = NULL;
8826   static GtkWidget *window2 = NULL;
8827   static GtkWidget *window3 = NULL;
8828   static GtkWidget *window4 = NULL;
8829
8830   if (window1 && 
8831      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
8832     {
8833       gtk_widget_destroy (window1);
8834       gtk_widget_destroy (window2);
8835       gtk_widget_destroy (window3);
8836       gtk_widget_destroy (window4);
8837     }
8838   
8839   if (!window1)
8840     {
8841       window1 = paned_keyboard_window1 (widget);
8842       gtk_signal_connect (GTK_OBJECT (window1), "destroy",
8843                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8844                           &window1);
8845     }
8846
8847   if (!window2)
8848     {
8849       window2 = paned_keyboard_window2 (widget);
8850       gtk_signal_connect (GTK_OBJECT (window2), "destroy",
8851                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8852                           &window2);
8853     }
8854
8855   if (!window3)
8856     {
8857       window3 = paned_keyboard_window3 (widget);
8858       gtk_signal_connect (GTK_OBJECT (window3), "destroy",
8859                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8860                           &window3);
8861     }
8862
8863   if (!window4)
8864     {
8865       window4 = paned_keyboard_window4 (widget);
8866       gtk_signal_connect (GTK_OBJECT (window4), "destroy",
8867                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8868                           &window4);
8869     }
8870
8871   if (GTK_WIDGET_VISIBLE (window1))
8872     gtk_widget_destroy (GTK_WIDGET (window1));
8873   else
8874     gtk_widget_show_all (GTK_WIDGET (window1));
8875
8876   if (GTK_WIDGET_VISIBLE (window2))
8877     gtk_widget_destroy (GTK_WIDGET (window2));
8878   else
8879     gtk_widget_show_all (GTK_WIDGET (window2));
8880
8881   if (GTK_WIDGET_VISIBLE (window3))
8882     gtk_widget_destroy (GTK_WIDGET (window3));
8883   else
8884     gtk_widget_show_all (GTK_WIDGET (window3));
8885
8886   if (GTK_WIDGET_VISIBLE (window4))
8887     gtk_widget_destroy (GTK_WIDGET (window4));
8888   else
8889     gtk_widget_show_all (GTK_WIDGET (window4));
8890 }
8891
8892
8893 /*
8894  * Shaped Windows
8895  */
8896
8897 typedef struct _cursoroffset {gint x,y;} CursorOffset;
8898
8899 static void
8900 shape_pressed (GtkWidget *widget, GdkEventButton *event)
8901 {
8902   CursorOffset *p;
8903
8904   /* ignore double and triple click */
8905   if (event->type != GDK_BUTTON_PRESS)
8906     return;
8907
8908   p = gtk_object_get_user_data (GTK_OBJECT(widget));
8909   p->x = (int) event->x;
8910   p->y = (int) event->y;
8911
8912   gtk_grab_add (widget);
8913   gdk_pointer_grab (widget->window, TRUE,
8914                     GDK_BUTTON_RELEASE_MASK |
8915                     GDK_BUTTON_MOTION_MASK |
8916                     GDK_POINTER_MOTION_HINT_MASK,
8917                     NULL, NULL, 0);
8918 }
8919
8920 static void
8921 shape_released (GtkWidget *widget)
8922 {
8923   gtk_grab_remove (widget);
8924   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
8925                               GDK_CURRENT_TIME);
8926 }
8927
8928 static void
8929 shape_motion (GtkWidget      *widget, 
8930               GdkEventMotion *event)
8931 {
8932   gint xp, yp;
8933   CursorOffset * p;
8934   GdkModifierType mask;
8935
8936   p = gtk_object_get_user_data (GTK_OBJECT (widget));
8937
8938   /*
8939    * Can't use event->x / event->y here 
8940    * because I need absolute coordinates.
8941    */
8942   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
8943   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
8944 }
8945
8946 GtkWidget *
8947 shape_create_icon (GdkScreen *screen,
8948                    char      *xpm_file,
8949                    gint       x,
8950                    gint       y,
8951                    gint       px,
8952                    gint       py,
8953                    gint       window_type)
8954 {
8955   GtkWidget *window;
8956   GtkWidget *pixmap;
8957   GtkWidget *fixed;
8958   CursorOffset* icon_pos;
8959   GdkGC* gc;
8960   GdkBitmap *gdk_pixmap_mask;
8961   GdkPixmap *gdk_pixmap;
8962   GtkStyle *style;
8963
8964   style = gtk_widget_get_default_style ();
8965   gc = style->black_gc; 
8966
8967   /*
8968    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
8969    */
8970   window = gtk_window_new (window_type);
8971   gtk_window_set_screen (GTK_WINDOW (window), screen);
8972   
8973   fixed = gtk_fixed_new ();
8974   gtk_widget_set_usize (fixed, 100,100);
8975   gtk_container_add (GTK_CONTAINER (window), fixed);
8976   gtk_widget_show (fixed);
8977   
8978   gtk_widget_set_events (window, 
8979                          gtk_widget_get_events (window) |
8980                          GDK_BUTTON_MOTION_MASK |
8981                          GDK_POINTER_MOTION_HINT_MASK |
8982                          GDK_BUTTON_PRESS_MASK);
8983
8984   gtk_widget_realize (window);
8985   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
8986                                            &style->bg[GTK_STATE_NORMAL],
8987                                            xpm_file);
8988
8989   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
8990   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
8991   gtk_widget_show (pixmap);
8992   
8993   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
8994   
8995   gdk_drawable_unref (gdk_pixmap_mask);
8996   gdk_drawable_unref (gdk_pixmap);
8997
8998   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
8999                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
9000   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
9001                       GTK_SIGNAL_FUNC (shape_released),NULL);
9002   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
9003                       GTK_SIGNAL_FUNC (shape_motion),NULL);
9004
9005   icon_pos = g_new (CursorOffset, 1);
9006   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
9007
9008   gtk_widget_set_uposition (window, x, y);
9009   gtk_widget_show (window);
9010   
9011   return window;
9012 }
9013
9014 void 
9015 create_shapes (GtkWidget *widget)
9016 {
9017   /* Variables used by the Drag/Drop and Shape Window demos */
9018   static GtkWidget *modeller = NULL;
9019   static GtkWidget *sheets = NULL;
9020   static GtkWidget *rings = NULL;
9021   static GtkWidget *with_region = NULL;
9022   GdkScreen *screen = gtk_widget_get_screen (widget);
9023   
9024   if (!(file_exists ("Modeller.xpm") &&
9025         file_exists ("FilesQueue.xpm") &&
9026         file_exists ("3DRings.xpm")))
9027     return;
9028   
9029
9030   if (!modeller)
9031     {
9032       modeller = shape_create_icon (screen, "Modeller.xpm",
9033                                     440, 140, 0,0, GTK_WINDOW_POPUP);
9034
9035       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
9036                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9037                           &modeller);
9038     }
9039   else
9040     gtk_widget_destroy (modeller);
9041
9042   if (!sheets)
9043     {
9044       sheets = shape_create_icon (screen, "FilesQueue.xpm",
9045                                   580, 170, 0,0, GTK_WINDOW_POPUP);
9046
9047       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
9048                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9049                           &sheets);
9050
9051     }
9052   else
9053     gtk_widget_destroy (sheets);
9054
9055   if (!rings)
9056     {
9057       rings = shape_create_icon (screen, "3DRings.xpm",
9058                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9059
9060       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
9061                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9062                           &rings);
9063     }
9064   else
9065     gtk_widget_destroy (rings);
9066
9067   if (!with_region)
9068     {
9069       GdkRegion *region;
9070       gint x, y;
9071       
9072       with_region = shape_create_icon (screen, "3DRings.xpm",
9073                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9074
9075       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
9076       
9077       gtk_signal_connect (GTK_OBJECT (with_region), "destroy",
9078                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9079                           &with_region);
9080
9081       /* reset shape from mask to a region */
9082       x = 0;
9083       y = 0;
9084       region = gdk_region_new ();
9085
9086       while (x < 460)
9087         {
9088           while (y < 270)
9089             {
9090               GdkRectangle rect;
9091               rect.x = x;
9092               rect.y = y;
9093               rect.width = 10;
9094               rect.height = 10;
9095
9096               gdk_region_union_with_rect (region, &rect);
9097               
9098               y += 20;
9099             }
9100           y = 0;
9101           x += 20;
9102         }
9103
9104       gdk_window_shape_combine_region (with_region->window,
9105                                        region,
9106                                        0, 0);
9107     }
9108   else
9109     gtk_widget_destroy (with_region);
9110 }
9111
9112 /*
9113  * WM Hints demo
9114  */
9115
9116 void
9117 create_wmhints (GtkWidget *widget)
9118 {
9119   static GtkWidget *window = NULL;
9120   GtkWidget *label;
9121   GtkWidget *separator;
9122   GtkWidget *button;
9123   GtkWidget *box1;
9124   GtkWidget *box2;
9125
9126   GdkBitmap *circles;
9127
9128   if (!window)
9129     {
9130       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9131
9132       gtk_window_set_screen (GTK_WINDOW (window),
9133                              gtk_widget_get_screen (widget));
9134       
9135       gtk_signal_connect (GTK_OBJECT (window), "destroy",
9136                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9137                           &window);
9138
9139       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
9140       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9141
9142       gtk_widget_realize (window);
9143       
9144       circles = gdk_bitmap_create_from_data (window->window,
9145                                              circles_bits,
9146                                              circles_width,
9147                                              circles_height);
9148       gdk_window_set_icon (window->window, NULL,
9149                            circles, circles);
9150       
9151       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
9152   
9153       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
9154       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
9155       
9156       box1 = gtk_vbox_new (FALSE, 0);
9157       gtk_container_add (GTK_CONTAINER (window), box1);
9158       gtk_widget_show (box1);
9159
9160       label = gtk_label_new ("Try iconizing me!");
9161       gtk_widget_set_usize (label, 150, 50);
9162       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
9163       gtk_widget_show (label);
9164
9165
9166       separator = gtk_hseparator_new ();
9167       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9168       gtk_widget_show (separator);
9169
9170
9171       box2 = gtk_vbox_new (FALSE, 10);
9172       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9173       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9174       gtk_widget_show (box2);
9175
9176
9177       button = gtk_button_new_with_label ("close");
9178
9179       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
9180                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9181                                  GTK_OBJECT (window));
9182
9183       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9184       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9185       gtk_widget_grab_default (button);
9186       gtk_widget_show (button);
9187     }
9188
9189   if (!GTK_WIDGET_VISIBLE (window))
9190     gtk_widget_show (window);
9191   else
9192     gtk_widget_destroy (window);
9193 }
9194
9195
9196 /*
9197  * Window state tracking
9198  */
9199
9200 static gint
9201 window_state_callback (GtkWidget *widget,
9202                        GdkEventWindowState *event,
9203                        gpointer data)
9204 {
9205   GtkWidget *label = data;
9206   gchar *msg;
9207
9208   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
9209                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
9210                      "withdrawn" : "not withdrawn", ", ",
9211                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
9212                      "iconified" : "not iconified", ", ",
9213                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
9214                      "sticky" : "not sticky", ", ",
9215                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
9216                      "maximized" : "not maximized", ", ",
9217                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
9218                      "fullscreen" : "not fullscreen",
9219                      NULL);
9220   
9221   gtk_label_set_text (GTK_LABEL (label), msg);
9222
9223   g_free (msg);
9224
9225   return FALSE;
9226 }
9227
9228 static GtkWidget*
9229 tracking_label (GtkWidget *window)
9230 {
9231   GtkWidget *label;
9232   GtkWidget *hbox;
9233   GtkWidget *button;
9234
9235   hbox = gtk_hbox_new (FALSE, 5);
9236
9237   gtk_signal_connect_object (GTK_OBJECT (hbox),
9238                              "destroy",
9239                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9240                              GTK_OBJECT (window));
9241   
9242   label = gtk_label_new ("<no window state events received>");
9243   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
9244   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
9245   
9246   gtk_signal_connect (GTK_OBJECT (window),
9247                       "window_state_event",
9248                       GTK_SIGNAL_FUNC (window_state_callback),
9249                       label);
9250
9251   button = gtk_button_new_with_label ("Deiconify");
9252   gtk_signal_connect_object (GTK_OBJECT (button),
9253                              "clicked",
9254                              GTK_SIGNAL_FUNC (gtk_window_deiconify),
9255                              GTK_OBJECT (window));
9256   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9257
9258   button = gtk_button_new_with_label ("Iconify");
9259   gtk_signal_connect_object (GTK_OBJECT (button),
9260                              "clicked",
9261                              GTK_SIGNAL_FUNC (gtk_window_iconify),
9262                              GTK_OBJECT (window));
9263   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9264
9265   button = gtk_button_new_with_label ("Fullscreen");
9266   gtk_signal_connect_object (GTK_OBJECT (button),
9267                              "clicked",
9268                              GTK_SIGNAL_FUNC (gtk_window_fullscreen),
9269                              GTK_OBJECT (window));
9270   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9271
9272   button = gtk_button_new_with_label ("Unfullscreen");
9273   gtk_signal_connect_object (GTK_OBJECT (button),
9274                              "clicked",
9275                              GTK_SIGNAL_FUNC (gtk_window_unfullscreen),
9276                              GTK_OBJECT (window));
9277   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9278   
9279   button = gtk_button_new_with_label ("Present");
9280   gtk_signal_connect_object (GTK_OBJECT (button),
9281                              "clicked",
9282                              GTK_SIGNAL_FUNC (gtk_window_present),
9283                              GTK_OBJECT (window));
9284   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9285
9286   button = gtk_button_new_with_label ("Show");
9287   gtk_signal_connect_object (GTK_OBJECT (button),
9288                              "clicked",
9289                              GTK_SIGNAL_FUNC (gtk_widget_show),
9290                              GTK_OBJECT (window));
9291   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9292   
9293   gtk_widget_show_all (hbox);
9294   
9295   return hbox;
9296 }
9297
9298 static GtkWidget*
9299 get_state_controls (GtkWidget *window)
9300 {
9301   GtkWidget *vbox;
9302   GtkWidget *button;
9303
9304   vbox = gtk_vbox_new (FALSE, 0);
9305   
9306   button = gtk_button_new_with_label ("Stick");
9307   gtk_signal_connect_object (GTK_OBJECT (button),
9308                              "clicked",
9309                              GTK_SIGNAL_FUNC (gtk_window_stick),
9310                              GTK_OBJECT (window));
9311   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9312
9313   button = gtk_button_new_with_label ("Unstick");
9314   gtk_signal_connect_object (GTK_OBJECT (button),
9315                              "clicked",
9316                              GTK_SIGNAL_FUNC (gtk_window_unstick),
9317                              GTK_OBJECT (window));
9318   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9319   
9320   button = gtk_button_new_with_label ("Maximize");
9321   gtk_signal_connect_object (GTK_OBJECT (button),
9322                              "clicked",
9323                              GTK_SIGNAL_FUNC (gtk_window_maximize),
9324                              GTK_OBJECT (window));
9325   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9326
9327   button = gtk_button_new_with_label ("Unmaximize");
9328   gtk_signal_connect_object (GTK_OBJECT (button),
9329                              "clicked",
9330                              GTK_SIGNAL_FUNC (gtk_window_unmaximize),
9331                              GTK_OBJECT (window));
9332   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9333
9334   button = gtk_button_new_with_label ("Iconify");
9335   gtk_signal_connect_object (GTK_OBJECT (button),
9336                              "clicked",
9337                              GTK_SIGNAL_FUNC (gtk_window_iconify),
9338                              GTK_OBJECT (window));
9339   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9340
9341   button = gtk_button_new_with_label ("Fullscreen");
9342   gtk_signal_connect_object (GTK_OBJECT (button),
9343                              "clicked",
9344                              GTK_SIGNAL_FUNC (gtk_window_fullscreen),
9345                              GTK_OBJECT (window));
9346   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9347
9348   button = gtk_button_new_with_label ("Unfullscreen");
9349   gtk_signal_connect_object (GTK_OBJECT (button),
9350                              "clicked",
9351                              GTK_SIGNAL_FUNC (gtk_window_unfullscreen),
9352                              GTK_OBJECT (window));
9353   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9354   
9355   button = gtk_button_new_with_label ("Hide (withdraw)");
9356   gtk_signal_connect_object (GTK_OBJECT (button),
9357                              "clicked",
9358                              GTK_SIGNAL_FUNC (gtk_widget_hide),
9359                              GTK_OBJECT (window));
9360   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9361   
9362   gtk_widget_show_all (vbox);
9363
9364   return vbox;
9365 }
9366
9367 void
9368 create_window_states (GtkWidget *widget)
9369 {
9370   static GtkWidget *window = NULL;
9371   GtkWidget *label;
9372   GtkWidget *box1;
9373   GtkWidget *iconified;
9374   GtkWidget *normal;
9375   GtkWidget *controls;
9376
9377   if (!window)
9378     {
9379       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9380       gtk_window_set_screen (GTK_WINDOW (window),
9381                              gtk_widget_get_screen (widget));
9382
9383       gtk_signal_connect (GTK_OBJECT (window), "destroy",
9384                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9385                           &window);
9386
9387       gtk_window_set_title (GTK_WINDOW (window), "Window states");
9388       
9389       box1 = gtk_vbox_new (FALSE, 0);
9390       gtk_container_add (GTK_CONTAINER (window), box1);
9391
9392       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9393
9394       gtk_window_set_screen (GTK_WINDOW (iconified),
9395                              gtk_widget_get_screen (widget));
9396       
9397       gtk_signal_connect_object (GTK_OBJECT (iconified), "destroy",
9398                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9399                                  GTK_OBJECT (window));
9400       gtk_window_iconify (GTK_WINDOW (iconified));
9401       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
9402       controls = get_state_controls (iconified);
9403       gtk_container_add (GTK_CONTAINER (iconified), controls);
9404       
9405       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9406
9407       gtk_window_set_screen (GTK_WINDOW (normal),
9408                              gtk_widget_get_screen (widget));
9409       
9410       gtk_signal_connect_object (GTK_OBJECT (normal), "destroy",
9411                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9412                                  GTK_OBJECT (window));
9413       
9414       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
9415       controls = get_state_controls (normal);
9416       gtk_container_add (GTK_CONTAINER (normal), controls);
9417       
9418       label = tracking_label (iconified);
9419       gtk_container_add (GTK_CONTAINER (box1), label);
9420
9421       label = tracking_label (normal);
9422       gtk_container_add (GTK_CONTAINER (box1), label);
9423
9424       gtk_widget_show_all (iconified);
9425       gtk_widget_show_all (normal);
9426       gtk_widget_show_all (box1);
9427     }
9428
9429   if (!GTK_WIDGET_VISIBLE (window))
9430     gtk_widget_show (window);
9431   else
9432     gtk_widget_destroy (window);
9433 }
9434
9435 /*
9436  * Window sizing
9437  */
9438
9439 static gint
9440 configure_event_callback (GtkWidget *widget,
9441                           GdkEventConfigure *event,
9442                           gpointer data)
9443 {
9444   GtkWidget *label = data;
9445   gchar *msg;
9446   gint x, y;
9447   
9448   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
9449   
9450   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
9451                          "position: %d, %d",
9452                          event->x, event->y, event->width, event->height,
9453                          x, y);
9454   
9455   gtk_label_set_text (GTK_LABEL (label), msg);
9456
9457   g_free (msg);
9458
9459   return FALSE;
9460 }
9461
9462 static void
9463 get_ints (GtkWidget *window,
9464           gint      *a,
9465           gint      *b)
9466 {
9467   GtkWidget *spin1;
9468   GtkWidget *spin2;
9469
9470   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
9471   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
9472
9473   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
9474   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
9475 }
9476
9477 static void
9478 set_size_callback (GtkWidget *widget,
9479                    gpointer   data)
9480 {
9481   gint w, h;
9482   
9483   get_ints (data, &w, &h);
9484
9485   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
9486 }
9487
9488 static void
9489 unset_default_size_callback (GtkWidget *widget,
9490                              gpointer   data)
9491 {
9492   gtk_window_set_default_size (g_object_get_data (data, "target"),
9493                                -1, -1);
9494 }
9495
9496 static void
9497 set_default_size_callback (GtkWidget *widget,
9498                            gpointer   data)
9499 {
9500   gint w, h;
9501   
9502   get_ints (data, &w, &h);
9503
9504   gtk_window_set_default_size (g_object_get_data (data, "target"),
9505                                w, h);
9506 }
9507
9508 static void
9509 unset_usize_callback (GtkWidget *widget,
9510                       gpointer   data)
9511 {
9512   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9513                                -1, -1);
9514 }
9515
9516 static void
9517 set_usize_callback (GtkWidget *widget,
9518                     gpointer   data)
9519 {
9520   gint w, h;
9521   
9522   get_ints (data, &w, &h);
9523
9524   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9525                                w, h);
9526 }
9527
9528 static void
9529 set_location_callback (GtkWidget *widget,
9530                        gpointer   data)
9531 {
9532   gint x, y;
9533   
9534   get_ints (data, &x, &y);
9535
9536   gtk_window_move (g_object_get_data (data, "target"), x, y);
9537 }
9538
9539 static void
9540 move_to_position_callback (GtkWidget *widget,
9541                            gpointer   data)
9542 {
9543   gint x, y;
9544   GtkWindow *window;
9545
9546   window = g_object_get_data (data, "target");
9547   
9548   gtk_window_get_position (window, &x, &y);
9549
9550   gtk_window_move (window, x, y);
9551 }
9552
9553 static void
9554 set_geometry_callback (GtkWidget *entry,
9555                        gpointer   data)
9556 {
9557   gchar *text;
9558   GtkWindow *target;
9559
9560   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
9561   
9562   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
9563
9564   if (!gtk_window_parse_geometry (target, text))
9565     g_print ("Bad geometry string '%s'\n", text);
9566
9567   g_free (text);
9568 }
9569
9570 static void
9571 allow_shrink_callback (GtkWidget *widget,
9572                        gpointer   data)
9573 {
9574   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9575                 "allow_shrink",
9576                 GTK_TOGGLE_BUTTON (widget)->active,
9577                 NULL);
9578 }
9579
9580 static void
9581 allow_grow_callback (GtkWidget *widget,
9582                      gpointer   data)
9583 {
9584   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9585                 "allow_grow",
9586                 GTK_TOGGLE_BUTTON (widget)->active,
9587                 NULL);
9588 }
9589
9590 static void
9591 auto_shrink_callback (GtkWidget *widget,
9592                       gpointer   data)
9593 {
9594   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9595                 "auto_shrink",
9596                 GTK_TOGGLE_BUTTON (widget)->active,
9597                 NULL);
9598 }
9599
9600 static void
9601 gravity_selected (GtkWidget *widget,
9602                   gpointer   data)
9603 {
9604   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
9605                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
9606 }
9607
9608 static void
9609 pos_selected (GtkWidget *widget,
9610               gpointer   data)
9611 {
9612   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
9613                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
9614 }
9615
9616 static void
9617 move_gravity_window_to_current_position (GtkWidget *widget,
9618                                          gpointer   data)
9619 {
9620   gint x, y;
9621   GtkWindow *window;
9622
9623   window = GTK_WINDOW (data);    
9624   
9625   gtk_window_get_position (window, &x, &y);
9626
9627   gtk_window_move (window, x, y);
9628 }
9629
9630 static void
9631 get_screen_corner (GtkWindow *window,
9632                    gint      *x,
9633                    gint      *y)
9634 {
9635   int w, h;
9636   GdkScreen * screen = gtk_window_get_screen (window);
9637   
9638   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
9639
9640   switch (gtk_window_get_gravity (window))
9641     {
9642     case GDK_GRAVITY_SOUTH_EAST:
9643       *x = gdk_screen_get_width (screen) - w;
9644       *y = gdk_screen_get_height (screen) - h;
9645       break;
9646
9647     case GDK_GRAVITY_NORTH_EAST:
9648       *x = gdk_screen_get_width (screen) - w;
9649       *y = 0;
9650       break;
9651
9652     case GDK_GRAVITY_SOUTH_WEST:
9653       *x = 0;
9654       *y = gdk_screen_get_height (screen) - h;
9655       break;
9656
9657     case GDK_GRAVITY_NORTH_WEST:
9658       *x = 0;
9659       *y = 0;
9660       break;
9661       
9662     case GDK_GRAVITY_SOUTH:
9663       *x = (gdk_screen_get_width (screen) - w) / 2;
9664       *y = gdk_screen_get_height (screen) - h;
9665       break;
9666
9667     case GDK_GRAVITY_NORTH:
9668       *x = (gdk_screen_get_width (screen) - w) / 2;
9669       *y = 0;
9670       break;
9671
9672     case GDK_GRAVITY_WEST:
9673       *x = 0;
9674       *y = (gdk_screen_get_height (screen) - h) / 2;
9675       break;
9676
9677     case GDK_GRAVITY_EAST:
9678       *x = gdk_screen_get_width (screen) - w;
9679       *y = (gdk_screen_get_height (screen) - h) / 2;
9680       break;
9681
9682     case GDK_GRAVITY_CENTER:
9683       *x = (gdk_screen_get_width (screen) - w) / 2;
9684       *y = (gdk_screen_get_height (screen) - h) / 2;
9685       break;
9686
9687     case GDK_GRAVITY_STATIC:
9688       /* pick some random numbers */
9689       *x = 350;
9690       *y = 350;
9691       break;
9692
9693     default:
9694       g_assert_not_reached ();
9695       break;
9696     }
9697 }
9698
9699 static void
9700 move_gravity_window_to_starting_position (GtkWidget *widget,
9701                                           gpointer   data)
9702 {
9703   gint x, y;
9704   GtkWindow *window;
9705
9706   window = GTK_WINDOW (data);    
9707   
9708   get_screen_corner (window,
9709                      &x, &y);
9710   
9711   gtk_window_move (window, x, y);
9712 }
9713
9714 static GtkWidget*
9715 make_gravity_window (GtkWidget   *destroy_with,
9716                      GdkGravity   gravity,
9717                      const gchar *title)
9718 {
9719   GtkWidget *window;
9720   GtkWidget *button;
9721   GtkWidget *vbox;
9722   int x, y;
9723   
9724   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9725
9726   gtk_window_set_screen (GTK_WINDOW (window),
9727                          gtk_widget_get_screen (destroy_with));
9728
9729   vbox = gtk_vbox_new (FALSE, 0);
9730   gtk_widget_show (vbox);
9731   
9732   gtk_container_add (GTK_CONTAINER (window), vbox);
9733   gtk_window_set_title (GTK_WINDOW (window), title);
9734   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
9735
9736   gtk_signal_connect_object (GTK_OBJECT (destroy_with),
9737                              "destroy",
9738                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9739                              GTK_OBJECT (window));
9740
9741   
9742   button = gtk_button_new_with_mnemonic ("_Move to current position");
9743
9744   g_signal_connect (G_OBJECT (button), "clicked",
9745                     G_CALLBACK (move_gravity_window_to_current_position),
9746                     window);
9747
9748   gtk_container_add (GTK_CONTAINER (vbox), button);
9749   gtk_widget_show (button);
9750
9751   button = gtk_button_new_with_mnemonic ("Move to _starting position");
9752
9753   g_signal_connect (G_OBJECT (button), "clicked",
9754                     G_CALLBACK (move_gravity_window_to_starting_position),
9755                     window);
9756
9757   gtk_container_add (GTK_CONTAINER (vbox), button);
9758   gtk_widget_show (button);
9759   
9760   /* Pretend this is the result of --geometry.
9761    * DO NOT COPY THIS CODE unless you are setting --geometry results,
9762    * and in that case you probably should just use gtk_window_parse_geometry().
9763    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
9764    * you are parsing --geometry or equivalent.
9765    */
9766   gtk_window_set_geometry_hints (GTK_WINDOW (window),
9767                                  NULL, NULL,
9768                                  GDK_HINT_USER_POS);
9769
9770   gtk_window_set_default_size (GTK_WINDOW (window),
9771                                200, 200);
9772
9773   get_screen_corner (GTK_WINDOW (window), &x, &y);
9774   
9775   gtk_window_move (GTK_WINDOW (window),
9776                    x, y);
9777   
9778   return window;
9779 }
9780
9781 static void
9782 do_gravity_test (GtkWidget *widget,
9783                  gpointer   data)
9784 {
9785   GtkWidget *destroy_with = data;
9786   GtkWidget *window;
9787   
9788   /* We put a window at each gravity point on the screen. */
9789   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
9790                                 "NorthWest");
9791   gtk_widget_show (window);
9792   
9793   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
9794                                 "SouthEast");
9795   gtk_widget_show (window);
9796
9797   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
9798                                 "NorthEast");
9799   gtk_widget_show (window);
9800
9801   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
9802                                 "SouthWest");
9803   gtk_widget_show (window);
9804
9805   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
9806                                 "South");
9807   gtk_widget_show (window);
9808
9809   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
9810                                 "North");
9811   gtk_widget_show (window);
9812
9813   
9814   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
9815                                 "West");
9816   gtk_widget_show (window);
9817
9818     
9819   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
9820                                 "East");
9821   gtk_widget_show (window);
9822
9823   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
9824                                 "Center");
9825   gtk_widget_show (window);
9826
9827   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
9828                                 "Static");
9829   gtk_widget_show (window);
9830 }
9831
9832 static GtkWidget*
9833 window_controls (GtkWidget *window)
9834 {
9835   GtkWidget *control_window;
9836   GtkWidget *label;
9837   GtkWidget *vbox;
9838   GtkWidget *button;
9839   GtkWidget *spin;
9840   GtkAdjustment *adj;
9841   GtkWidget *entry;
9842   GtkWidget *om;
9843   GtkWidget *menu;
9844   gint i;
9845   
9846   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9847
9848   gtk_window_set_screen (GTK_WINDOW (control_window),
9849                          gtk_widget_get_screen (window));
9850
9851   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
9852   
9853   g_object_set_data (G_OBJECT (control_window),
9854                      "target",
9855                      window);
9856   
9857   gtk_signal_connect_object (GTK_OBJECT (control_window),
9858                              "destroy",
9859                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9860                              GTK_OBJECT (window));
9861
9862   vbox = gtk_vbox_new (FALSE, 5);
9863   
9864   gtk_container_add (GTK_CONTAINER (control_window), vbox);
9865   
9866   label = gtk_label_new ("<no configure events>");
9867   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9868   
9869   gtk_signal_connect (GTK_OBJECT (window),
9870                       "configure_event",
9871                       GTK_SIGNAL_FUNC (configure_event_callback),
9872                       label);
9873
9874   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9875                                               5.0, 0.0);
9876   spin = gtk_spin_button_new (adj, 0, 0);
9877
9878   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9879
9880   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
9881
9882   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9883                                               5.0, 0.0);
9884   spin = gtk_spin_button_new (adj, 0, 0);
9885
9886   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9887
9888   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
9889
9890   entry = gtk_entry_new ();
9891   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9892
9893   gtk_signal_connect (GTK_OBJECT (entry), "changed",
9894                       GTK_SIGNAL_FUNC (set_geometry_callback),
9895                       control_window);
9896
9897   button = gtk_button_new_with_label ("Show gravity test windows");
9898   gtk_signal_connect_object (GTK_OBJECT (button),
9899                              "clicked",
9900                              GTK_SIGNAL_FUNC (do_gravity_test),
9901                              control_window);
9902   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9903
9904   button = gtk_button_new_with_label ("Reshow with initial size");
9905   gtk_signal_connect_object (GTK_OBJECT (button),
9906                              "clicked",
9907                              GTK_SIGNAL_FUNC (gtk_window_reshow_with_initial_size),
9908                              GTK_OBJECT (window));
9909   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9910   
9911   button = gtk_button_new_with_label ("Queue resize");
9912   gtk_signal_connect_object (GTK_OBJECT (button),
9913                              "clicked",
9914                              GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
9915                              GTK_OBJECT (window));
9916   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9917   
9918   button = gtk_button_new_with_label ("Resize");
9919   gtk_signal_connect (GTK_OBJECT (button),
9920                       "clicked",
9921                       GTK_SIGNAL_FUNC (set_size_callback),
9922                       GTK_OBJECT (control_window));
9923   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9924
9925   button = gtk_button_new_with_label ("Set default size");
9926   gtk_signal_connect (GTK_OBJECT (button),
9927                       "clicked",
9928                       GTK_SIGNAL_FUNC (set_default_size_callback),
9929                       GTK_OBJECT (control_window));
9930   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9931
9932   button = gtk_button_new_with_label ("Unset default size");
9933   gtk_signal_connect (GTK_OBJECT (button),
9934                       "clicked",
9935                       GTK_SIGNAL_FUNC (unset_default_size_callback),
9936                       GTK_OBJECT (control_window));
9937   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9938   
9939   button = gtk_button_new_with_label ("Set size request");
9940   gtk_signal_connect (GTK_OBJECT (button),
9941                       "clicked",
9942                       GTK_SIGNAL_FUNC (set_usize_callback),
9943                       GTK_OBJECT (control_window));
9944   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9945
9946   button = gtk_button_new_with_label ("Unset size request");
9947   gtk_signal_connect (GTK_OBJECT (button),
9948                       "clicked",
9949                       GTK_SIGNAL_FUNC (unset_usize_callback),
9950                       GTK_OBJECT (control_window));
9951   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9952   
9953   button = gtk_button_new_with_label ("Move");
9954   gtk_signal_connect (GTK_OBJECT (button),
9955                       "clicked",
9956                       GTK_SIGNAL_FUNC (set_location_callback),
9957                       GTK_OBJECT (control_window));
9958   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9959
9960   button = gtk_button_new_with_label ("Move to current position");
9961   gtk_signal_connect (GTK_OBJECT (button),
9962                       "clicked",
9963                       GTK_SIGNAL_FUNC (move_to_position_callback),
9964                       GTK_OBJECT (control_window));
9965   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9966   
9967   button = gtk_check_button_new_with_label ("Allow shrink");
9968   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9969   gtk_signal_connect (GTK_OBJECT (button),
9970                       "toggled",
9971                       GTK_SIGNAL_FUNC (allow_shrink_callback),
9972                       GTK_OBJECT (control_window));
9973   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9974
9975   button = gtk_check_button_new_with_label ("Allow grow");
9976   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
9977   gtk_signal_connect (GTK_OBJECT (button),
9978                       "toggled",
9979                       GTK_SIGNAL_FUNC (allow_grow_callback),
9980                       GTK_OBJECT (control_window));
9981   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9982   
9983   button = gtk_check_button_new_with_label ("Auto shrink");
9984   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9985   gtk_signal_connect (GTK_OBJECT (button),
9986                       "toggled",
9987                       GTK_SIGNAL_FUNC (auto_shrink_callback),
9988                       GTK_OBJECT (control_window));
9989   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9990
9991   button = gtk_button_new_with_mnemonic ("_Show");
9992   gtk_signal_connect_object (GTK_OBJECT (button),
9993                              "clicked",
9994                              GTK_SIGNAL_FUNC (gtk_widget_show),
9995                              GTK_OBJECT (window));
9996   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9997
9998   button = gtk_button_new_with_mnemonic ("_Hide");
9999   gtk_signal_connect_object (GTK_OBJECT (button),
10000                              "clicked",
10001                              GTK_SIGNAL_FUNC (gtk_widget_hide),
10002                              GTK_OBJECT (window));
10003   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10004   
10005   menu = gtk_menu_new ();
10006   
10007   i = 0;
10008   while (i < 10)
10009     {
10010       GtkWidget *mi;
10011       static gchar *names[] = {
10012         "GDK_GRAVITY_NORTH_WEST",
10013         "GDK_GRAVITY_NORTH",
10014         "GDK_GRAVITY_NORTH_EAST",
10015         "GDK_GRAVITY_WEST",
10016         "GDK_GRAVITY_CENTER",
10017         "GDK_GRAVITY_EAST",
10018         "GDK_GRAVITY_SOUTH_WEST",
10019         "GDK_GRAVITY_SOUTH",
10020         "GDK_GRAVITY_SOUTH_EAST",
10021         "GDK_GRAVITY_STATIC",
10022         NULL
10023       };
10024
10025       g_assert (names[i]);
10026       
10027       mi = gtk_menu_item_new_with_label (names[i]);
10028
10029       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10030
10031       ++i;
10032     }
10033   
10034   gtk_widget_show_all (menu);
10035   
10036   om = gtk_option_menu_new ();
10037   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10038   
10039
10040   gtk_signal_connect (GTK_OBJECT (om),
10041                       "changed",
10042                       GTK_SIGNAL_FUNC (gravity_selected),
10043                       control_window);
10044
10045   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10046
10047
10048   menu = gtk_menu_new ();
10049   
10050   i = 0;
10051   while (i < 5)
10052     {
10053       GtkWidget *mi;
10054       static gchar *names[] = {
10055         "GTK_WIN_POS_NONE",
10056         "GTK_WIN_POS_CENTER",
10057         "GTK_WIN_POS_MOUSE",
10058         "GTK_WIN_POS_CENTER_ALWAYS",
10059         "GTK_WIN_POS_CENTER_ON_PARENT",
10060         NULL
10061       };
10062
10063       g_assert (names[i]);
10064       
10065       mi = gtk_menu_item_new_with_label (names[i]);
10066
10067       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10068
10069       ++i;
10070     }
10071   
10072   gtk_widget_show_all (menu);
10073   
10074   om = gtk_option_menu_new ();
10075   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10076   
10077
10078   gtk_signal_connect (GTK_OBJECT (om),
10079                       "changed",
10080                       GTK_SIGNAL_FUNC (pos_selected),
10081                       control_window);
10082
10083   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10084   
10085   gtk_widget_show_all (vbox);
10086   
10087   return control_window;
10088 }
10089
10090 void
10091 create_window_sizing (GtkWidget *widget)
10092 {
10093   static GtkWidget *window = NULL;
10094   static GtkWidget *target_window = NULL;
10095
10096   if (!target_window)
10097     {
10098       GtkWidget *label;
10099       
10100       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10101       gtk_window_set_screen (GTK_WINDOW (target_window),
10102                              gtk_widget_get_screen (widget));
10103       label = gtk_label_new (NULL);
10104       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");
10105       gtk_container_add (GTK_CONTAINER (target_window), label);
10106       gtk_widget_show (label);
10107       
10108       gtk_signal_connect (GTK_OBJECT (target_window), "destroy",
10109                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
10110                           &target_window);
10111
10112       window = window_controls (target_window);
10113       
10114       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10115                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
10116                           &window);
10117       
10118       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
10119     }
10120
10121   /* don't show target window by default, we want to allow testing
10122    * of behavior on first show.
10123    */
10124   
10125   if (!GTK_WIDGET_VISIBLE (window))
10126     gtk_widget_show (window);
10127   else
10128     gtk_widget_destroy (window);
10129 }
10130
10131 /*
10132  * GtkProgressBar
10133  */
10134
10135 typedef struct _ProgressData {
10136   GtkWidget *window;
10137   GtkWidget *pbar;
10138   GtkWidget *block_spin;
10139   GtkWidget *x_align_spin;
10140   GtkWidget *y_align_spin;
10141   GtkWidget *step_spin;
10142   GtkWidget *act_blocks_spin;
10143   GtkWidget *label;
10144   GtkWidget *omenu1;
10145   GtkWidget *omenu2;
10146   GtkWidget *entry;
10147   int timer;
10148 } ProgressData;
10149
10150 gint
10151 progress_timeout (gpointer data)
10152 {
10153   gdouble new_val;
10154   GtkAdjustment *adj;
10155
10156   adj = GTK_PROGRESS (data)->adjustment;
10157
10158   new_val = adj->value + 1;
10159   if (new_val > adj->upper)
10160     new_val = adj->lower;
10161
10162   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
10163
10164   return TRUE;
10165 }
10166
10167 static void
10168 destroy_progress (GtkWidget     *widget,
10169                   ProgressData **pdata)
10170 {
10171   gtk_timeout_remove ((*pdata)->timer);
10172   (*pdata)->timer = 0;
10173   (*pdata)->window = NULL;
10174   g_free (*pdata);
10175   *pdata = NULL;
10176 }
10177
10178 static void
10179 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
10180 {
10181   ProgressData *pdata;
10182   gint i;
10183
10184   pdata = (ProgressData *) data;
10185
10186   if (!GTK_WIDGET_MAPPED (widget))
10187     return;
10188
10189   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10190
10191   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
10192                                     (GtkProgressBarOrientation) i);
10193 }
10194
10195 static void
10196 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
10197 {
10198   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
10199                               GTK_TOGGLE_BUTTON (widget)->active);
10200   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
10201   gtk_widget_set_sensitive (pdata->x_align_spin,
10202                             GTK_TOGGLE_BUTTON (widget)->active);
10203   gtk_widget_set_sensitive (pdata->y_align_spin,
10204                             GTK_TOGGLE_BUTTON (widget)->active);
10205 }
10206
10207 static void
10208 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
10209 {
10210   ProgressData *pdata;
10211   gint i;
10212
10213   pdata = (ProgressData *) data;
10214
10215   if (!GTK_WIDGET_MAPPED (widget))
10216     return;
10217
10218   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10219
10220   if (i == 1)
10221     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
10222   else
10223     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10224   
10225   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
10226                                   (GtkProgressBarStyle) i);
10227 }
10228
10229 static void
10230 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
10231 {
10232   char buf[20];
10233
10234   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
10235     sprintf (buf, "???");
10236   else
10237     sprintf (buf, "%.0f%%", 100 *
10238              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
10239   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
10240 }
10241
10242 static void
10243 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
10244 {
10245   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
10246   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10247      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
10248 }
10249
10250 static void
10251 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
10252 {
10253   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
10254      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
10255 }
10256
10257 static void
10258 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
10259 {
10260   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10261                gtk_spin_button_get_value_as_int 
10262                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
10263 }
10264
10265 static void
10266 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
10267 {
10268   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
10269          gtk_spin_button_get_value_as_float 
10270                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
10271          gtk_spin_button_get_value_as_float
10272                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
10273 }
10274
10275 static void
10276 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
10277 {
10278   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
10279                                   GTK_TOGGLE_BUTTON (widget)->active);
10280   gtk_widget_set_sensitive (pdata->step_spin, 
10281                             GTK_TOGGLE_BUTTON (widget)->active);
10282   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
10283                             GTK_TOGGLE_BUTTON (widget)->active);
10284 }
10285
10286 static void
10287 entry_changed (GtkWidget *widget, ProgressData *pdata)
10288 {
10289   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10290                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
10291 }
10292
10293 void
10294 create_progress_bar (GtkWidget *widget)
10295 {
10296   GtkWidget *button;
10297   GtkWidget *vbox;
10298   GtkWidget *vbox2;
10299   GtkWidget *hbox;
10300   GtkWidget *check;
10301   GtkWidget *frame;
10302   GtkWidget *tab;
10303   GtkWidget *label;
10304   GtkWidget *align;
10305   GtkAdjustment *adj;
10306   static ProgressData *pdata = NULL;
10307
10308   static gchar *items1[] =
10309   {
10310     "Left-Right",
10311     "Right-Left",
10312     "Bottom-Top",
10313     "Top-Bottom"
10314   };
10315
10316   static gchar *items2[] =
10317   {
10318     "Continuous",
10319     "Discrete"
10320   };
10321   
10322   if (!pdata)
10323     pdata = g_new0 (ProgressData, 1);
10324
10325   if (!pdata->window)
10326     {
10327       pdata->window = gtk_dialog_new ();
10328
10329       gtk_window_set_screen (GTK_WINDOW (pdata->window),
10330                              gtk_widget_get_screen (widget));
10331
10332       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
10333
10334       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
10335                           GTK_SIGNAL_FUNC (destroy_progress),
10336                           &pdata);
10337
10338       pdata->timer = 0;
10339
10340       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
10341       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
10342
10343       vbox = gtk_vbox_new (FALSE, 5);
10344       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
10345       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
10346                           vbox, FALSE, TRUE, 0);
10347
10348       frame = gtk_frame_new ("Progress");
10349       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10350
10351       vbox2 = gtk_vbox_new (FALSE, 5);
10352       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10353
10354       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10355       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10356
10357       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
10358       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10359                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
10360
10361       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
10362       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10363                                       "%v from [%l,%u] (=%p%%)");
10364       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
10365       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
10366
10367       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10368       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10369
10370       hbox = gtk_hbox_new (FALSE, 5);
10371       gtk_container_add (GTK_CONTAINER (align), hbox);
10372       label = gtk_label_new ("Label updated by user :"); 
10373       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10374       pdata->label = gtk_label_new ("");
10375       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
10376
10377       frame = gtk_frame_new ("Options");
10378       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10379
10380       vbox2 = gtk_vbox_new (FALSE, 5);
10381       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10382
10383       tab = gtk_table_new (7, 2, FALSE);
10384       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
10385
10386       label = gtk_label_new ("Orientation :");
10387       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
10388                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10389                         5, 5);
10390       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10391
10392       pdata->omenu1 = build_option_menu (items1, 4, 0,
10393                                          progressbar_toggle_orientation,
10394                                          pdata);
10395       hbox = gtk_hbox_new (FALSE, 0);
10396       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
10397                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10398                         5, 5);
10399       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
10400       
10401       check = gtk_check_button_new_with_label ("Show text");
10402       gtk_signal_connect (GTK_OBJECT (check), "clicked",
10403                           GTK_SIGNAL_FUNC (toggle_show_text),
10404                           pdata);
10405       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
10406                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10407                         5, 5);
10408
10409       hbox = gtk_hbox_new (FALSE, 0);
10410       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
10411                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10412                         5, 5);
10413
10414       label = gtk_label_new ("Format : ");
10415       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10416
10417       pdata->entry = gtk_entry_new ();
10418       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
10419                           GTK_SIGNAL_FUNC (entry_changed),
10420                           pdata);
10421       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
10422       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
10423       gtk_widget_set_usize (pdata->entry, 100, -1);
10424       gtk_widget_set_sensitive (pdata->entry, FALSE);
10425
10426       label = gtk_label_new ("Text align :");
10427       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
10428                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10429                         5, 5);
10430       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10431
10432       hbox = gtk_hbox_new (FALSE, 0);
10433       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
10434                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10435                         5, 5);
10436
10437       label = gtk_label_new ("x :");
10438       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10439       
10440       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10441       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
10442       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10443                           GTK_SIGNAL_FUNC (adjust_align), pdata);
10444       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
10445       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
10446
10447       label = gtk_label_new ("y :");
10448       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10449
10450       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10451       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
10452       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10453                           GTK_SIGNAL_FUNC (adjust_align), pdata);
10454       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
10455       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
10456
10457       label = gtk_label_new ("Bar Style :");
10458       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
10459                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10460                         5, 5);
10461       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10462
10463       pdata->omenu2 = build_option_menu (items2, 2, 0,
10464                                          progressbar_toggle_bar_style,
10465                                          pdata);
10466       hbox = gtk_hbox_new (FALSE, 0);
10467       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
10468                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10469                         5, 5);
10470       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
10471
10472       label = gtk_label_new ("Block count :");
10473       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
10474                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10475                         5, 5);
10476       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10477
10478       hbox = gtk_hbox_new (FALSE, 0);
10479       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
10480                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10481                         5, 5);
10482       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
10483       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
10484       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10485                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
10486       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
10487       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10488
10489       check = gtk_check_button_new_with_label ("Activity mode");
10490       gtk_signal_connect (GTK_OBJECT (check), "clicked",
10491                           GTK_SIGNAL_FUNC (toggle_activity_mode),
10492                           pdata);
10493       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
10494                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10495                         5, 5);
10496
10497       hbox = gtk_hbox_new (FALSE, 0);
10498       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
10499                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10500                         5, 5);
10501       label = gtk_label_new ("Step size : ");
10502       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10503       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
10504       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
10505       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10506                           GTK_SIGNAL_FUNC (adjust_step), pdata);
10507       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
10508       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
10509
10510       hbox = gtk_hbox_new (FALSE, 0);
10511       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
10512                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10513                         5, 5);
10514       label = gtk_label_new ("Blocks :     ");
10515       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10516       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
10517       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
10518       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10519                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
10520       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
10521                           0);
10522       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
10523
10524       button = gtk_button_new_with_label ("close");
10525       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10526                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
10527                                  GTK_OBJECT (pdata->window));
10528       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10529       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
10530                           button, TRUE, TRUE, 0);
10531       gtk_widget_grab_default (button);
10532     }
10533
10534   if (!GTK_WIDGET_VISIBLE (pdata->window))
10535     gtk_widget_show_all (pdata->window);
10536   else
10537     gtk_widget_destroy (pdata->window);
10538 }
10539
10540 /*
10541  * Properties
10542  */
10543
10544 typedef struct {
10545   int x;
10546   int y;
10547   gboolean found;
10548   gboolean first;
10549   GtkWidget *res_widget;
10550 } FindWidgetData;
10551
10552 static void
10553 find_widget (GtkWidget *widget, FindWidgetData *data)
10554 {
10555   GtkAllocation new_allocation;
10556   gint x_offset = 0;
10557   gint y_offset = 0;
10558
10559   new_allocation = widget->allocation;
10560
10561   if (data->found || !GTK_WIDGET_MAPPED (widget))
10562     return;
10563
10564   /* Note that in the following code, we only count the
10565    * position as being inside a WINDOW widget if it is inside
10566    * widget->window; points that are outside of widget->window
10567    * but within the allocation are not counted. This is consistent
10568    * with the way we highlight drag targets.
10569    */
10570   if (!GTK_WIDGET_NO_WINDOW (widget))
10571     {
10572       new_allocation.x = 0;
10573       new_allocation.y = 0;
10574     }
10575   
10576   if (widget->parent && !data->first)
10577     {
10578       GdkWindow *window = widget->window;
10579       while (window != widget->parent->window)
10580         {
10581           gint tx, ty, twidth, theight;
10582           gdk_window_get_size (window, &twidth, &theight);
10583
10584           if (new_allocation.x < 0)
10585             {
10586               new_allocation.width += new_allocation.x;
10587               new_allocation.x = 0;
10588             }
10589           if (new_allocation.y < 0)
10590             {
10591               new_allocation.height += new_allocation.y;
10592               new_allocation.y = 0;
10593             }
10594           if (new_allocation.x + new_allocation.width > twidth)
10595             new_allocation.width = twidth - new_allocation.x;
10596           if (new_allocation.y + new_allocation.height > theight)
10597             new_allocation.height = theight - new_allocation.y;
10598
10599           gdk_window_get_position (window, &tx, &ty);
10600           new_allocation.x += tx;
10601           x_offset += tx;
10602           new_allocation.y += ty;
10603           y_offset += ty;
10604           
10605           window = gdk_window_get_parent (window);
10606         }
10607     }
10608
10609   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
10610       (data->x < new_allocation.x + new_allocation.width) && 
10611       (data->y < new_allocation.y + new_allocation.height))
10612     {
10613       /* First, check if the drag is in a valid drop site in
10614        * one of our children 
10615        */
10616       if (GTK_IS_CONTAINER (widget))
10617         {
10618           FindWidgetData new_data = *data;
10619           
10620           new_data.x -= x_offset;
10621           new_data.y -= y_offset;
10622           new_data.found = FALSE;
10623           new_data.first = FALSE;
10624           
10625           gtk_container_forall (GTK_CONTAINER (widget),
10626                                 (GtkCallback)find_widget,
10627                                 &new_data);
10628           
10629           data->found = new_data.found;
10630           if (data->found)
10631             data->res_widget = new_data.res_widget;
10632         }
10633
10634       /* If not, and this widget is registered as a drop site, check to
10635        * emit "drag_motion" to check if we are actually in
10636        * a drop site.
10637        */
10638       if (!data->found)
10639         {
10640           data->found = TRUE;
10641           data->res_widget = widget;
10642         }
10643     }
10644 }
10645
10646 static GtkWidget *
10647 find_widget_at_pointer (GdkDisplay *display)
10648 {
10649   GtkWidget *widget = NULL;
10650   GdkWindow *pointer_window;
10651   gint x, y;
10652   FindWidgetData data;
10653  
10654  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);
10655  
10656  if (pointer_window)
10657    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);
10658
10659  if (widget)
10660    {
10661      gdk_window_get_pointer (widget->window,
10662                              &x, &y, NULL);
10663      
10664      data.x = x;
10665      data.y = y;
10666      data.found = FALSE;
10667      data.first = TRUE;
10668
10669      find_widget (widget, &data);
10670      if (data.found)
10671        return data.res_widget;
10672      return widget;
10673    }
10674  return NULL;
10675 }
10676
10677 struct PropertiesData {
10678   GtkWidget **window;
10679   GdkCursor *cursor;
10680   gboolean in_query;
10681   gint handler;
10682 };
10683
10684 static void
10685 destroy_properties (GtkWidget             *widget,
10686                     struct PropertiesData *data)
10687 {
10688   if (data->window)
10689     {
10690       *data->window = NULL;
10691       data->window = NULL;
10692     }
10693
10694   if (data->cursor)
10695     {
10696       gdk_cursor_destroy (data->cursor);
10697       data->cursor = NULL;
10698     }
10699
10700   if (data->handler)
10701     {
10702       gtk_signal_disconnect (widget, data->handler);
10703       data->handler = 0;
10704     }
10705
10706   g_free (data);
10707 }
10708
10709 static gint
10710 property_query_event (GtkWidget        *widget,
10711                       GdkEvent         *event,
10712                       struct PropertiesData *data)
10713 {
10714   GtkWidget *res_widget = NULL;
10715
10716   if (!data->in_query)
10717     return FALSE;
10718   
10719   if (event->type == GDK_BUTTON_RELEASE)
10720     {
10721       gtk_grab_remove (widget);
10722       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
10723                                   GDK_CURRENT_TIME);
10724       
10725       res_widget = find_widget_at_pointer (gtk_widget_get_display (widget));
10726       if (res_widget)
10727         {
10728           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
10729                              gtk_widget_get_screen (widget));
10730           create_prop_editor (G_OBJECT (res_widget), 0);
10731         }
10732
10733       data->in_query = FALSE;
10734     }
10735   return FALSE;
10736 }
10737
10738
10739 static void
10740 query_properties (GtkButton *button,
10741                   struct PropertiesData *data)
10742 {
10743   gint failure;
10744
10745   gtk_signal_connect (GTK_OBJECT (button), "event",
10746                       (GtkSignalFunc) property_query_event, data);
10747
10748
10749   if (!data->cursor)
10750     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (button)),
10751                                                GDK_TARGET);
10752   
10753   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
10754                               TRUE,
10755                               GDK_BUTTON_RELEASE_MASK,
10756                               NULL,
10757                               data->cursor,
10758                               GDK_CURRENT_TIME);
10759
10760   gtk_grab_add (GTK_WIDGET (button));
10761
10762   data->in_query = TRUE;
10763 }
10764
10765 static void
10766 create_properties (GtkWidget *widget)
10767 {
10768   static GtkWidget *window = NULL;
10769   GtkWidget *button;
10770   GtkWidget *vbox;
10771   GtkWidget *label;
10772   struct PropertiesData *data;
10773
10774   data = g_new (struct PropertiesData, 1);
10775   data->window = &window;
10776   data->in_query = FALSE;
10777   data->cursor = NULL;
10778   data->handler = 0;
10779
10780   if (!window)
10781     {
10782       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10783
10784       gtk_window_set_screen (GTK_WINDOW (window),
10785                              gtk_widget_get_screen (widget));      
10786
10787       data->handler = gtk_signal_connect (GTK_OBJECT (window), "destroy",
10788                                           GTK_SIGNAL_FUNC(destroy_properties),
10789                                           data);
10790
10791       gtk_window_set_title (GTK_WINDOW (window), "test properties");
10792       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10793
10794       vbox = gtk_vbox_new (FALSE, 1);
10795       gtk_container_add (GTK_CONTAINER (window), vbox);
10796             
10797       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
10798       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
10799       
10800       button = gtk_button_new_with_label ("Query properties");
10801       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
10802       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10803                           GTK_SIGNAL_FUNC(query_properties),
10804                           data);
10805     }
10806
10807   if (!GTK_WIDGET_VISIBLE (window))
10808     gtk_widget_show_all (window);
10809   else
10810     gtk_widget_destroy (window);
10811   
10812 }
10813
10814
10815 /*
10816  * Color Preview
10817  */
10818
10819 static int color_idle = 0;
10820
10821 gint
10822 color_idle_func (GtkWidget *preview)
10823 {
10824   static int count = 1;
10825   guchar buf[768];
10826   int i, j, k;
10827
10828   for (i = 0; i < 256; i++)
10829     {
10830       for (j = 0, k = 0; j < 256; j++)
10831         {
10832           buf[k+0] = i + count;
10833           buf[k+1] = 0;
10834           buf[k+2] = j + count;
10835           k += 3;
10836         }
10837
10838       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10839     }
10840
10841   count += 1;
10842
10843   gtk_widget_draw (preview, NULL);
10844
10845   return TRUE;
10846 }
10847
10848 static void
10849 color_preview_destroy (GtkWidget  *widget,
10850                        GtkWidget **window)
10851 {
10852   gtk_idle_remove (color_idle);
10853   color_idle = 0;
10854
10855   *window = NULL;
10856 }
10857
10858 void
10859 create_color_preview (GtkWidget *widget)
10860 {
10861   static GtkWidget *window = NULL;
10862   GtkWidget *preview;
10863   guchar buf[768];
10864   int i, j, k;
10865
10866   if (!window)
10867     {
10868       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10869       
10870       gtk_window_set_screen (GTK_WINDOW (window),
10871                              gtk_widget_get_screen (widget));
10872
10873       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10874                           GTK_SIGNAL_FUNC(color_preview_destroy),
10875                           &window);
10876
10877       gtk_window_set_title (GTK_WINDOW (window), "test");
10878       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10879
10880       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
10881       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10882       gtk_container_add (GTK_CONTAINER (window), preview);
10883
10884       for (i = 0; i < 256; i++)
10885         {
10886           for (j = 0, k = 0; j < 256; j++)
10887             {
10888               buf[k+0] = i;
10889               buf[k+1] = 0;
10890               buf[k+2] = j;
10891               k += 3;
10892             }
10893
10894           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10895         }
10896
10897       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
10898     }
10899
10900   if (!GTK_WIDGET_VISIBLE (window))
10901     gtk_widget_show_all (window);
10902   else
10903     gtk_widget_destroy (window);
10904 }
10905
10906 /*
10907  * Gray Preview
10908  */
10909
10910 static int gray_idle = 0;
10911
10912 gint
10913 gray_idle_func (GtkWidget *preview)
10914 {
10915   static int count = 1;
10916   guchar buf[256];
10917   int i, j;
10918
10919   for (i = 0; i < 256; i++)
10920     {
10921       for (j = 0; j < 256; j++)
10922         buf[j] = i + j + count;
10923
10924       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10925     }
10926
10927   count += 1;
10928
10929   gtk_widget_draw (preview, NULL);
10930
10931   return TRUE;
10932 }
10933
10934 static void
10935 gray_preview_destroy (GtkWidget  *widget,
10936                       GtkWidget **window)
10937 {
10938   gtk_idle_remove (gray_idle);
10939   gray_idle = 0;
10940
10941   *window = NULL;
10942 }
10943
10944 void
10945 create_gray_preview (GtkWidget *widget)
10946 {
10947   static GtkWidget *window = NULL;
10948   GtkWidget *preview;
10949   guchar buf[256];
10950   int i, j;
10951
10952   if (!window)
10953     {
10954       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10955
10956       gtk_window_set_screen (GTK_WINDOW (window),
10957                              gtk_widget_get_screen (widget));
10958
10959       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10960                           GTK_SIGNAL_FUNC(gray_preview_destroy),
10961                           &window);
10962
10963       gtk_window_set_title (GTK_WINDOW (window), "test");
10964       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10965
10966       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
10967       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10968       gtk_container_add (GTK_CONTAINER (window), preview);
10969
10970       for (i = 0; i < 256; i++)
10971         {
10972           for (j = 0; j < 256; j++)
10973             buf[j] = i + j;
10974
10975           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10976         }
10977
10978       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
10979     }
10980
10981   if (!GTK_WIDGET_VISIBLE (window))
10982     gtk_widget_show_all (window);
10983   else
10984     gtk_widget_destroy (window);
10985 }
10986
10987
10988 /*
10989  * Selection Test
10990  */
10991
10992 void
10993 selection_test_received (GtkWidget *list, GtkSelectionData *data)
10994 {
10995   GdkAtom *atoms;
10996   GtkWidget *list_item;
10997   GList *item_list;
10998   int i, l;
10999
11000   if (data->length < 0)
11001     {
11002       g_print ("Selection retrieval failed\n");
11003       return;
11004     }
11005   if (data->type != GDK_SELECTION_TYPE_ATOM)
11006     {
11007       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
11008       return;
11009     }
11010
11011   /* Clear out any current list items */
11012
11013   gtk_list_clear_items (GTK_LIST(list), 0, -1);
11014
11015   /* Add new items to list */
11016
11017   atoms = (GdkAtom *)data->data;
11018
11019   item_list = NULL;
11020   l = data->length / sizeof (GdkAtom);
11021   for (i = 0; i < l; i++)
11022     {
11023       char *name;
11024       name = gdk_atom_name (atoms[i]);
11025       if (name != NULL)
11026         {
11027           list_item = gtk_list_item_new_with_label (name);
11028           g_free (name);
11029         }
11030       else
11031         list_item = gtk_list_item_new_with_label ("(bad atom)");
11032
11033       gtk_widget_show (list_item);
11034       item_list = g_list_append (item_list, list_item);
11035     }
11036
11037   gtk_list_append_items (GTK_LIST (list), item_list);
11038
11039   return;
11040 }
11041
11042 void
11043 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
11044 {
11045   static GdkAtom targets_atom = GDK_NONE;
11046
11047   if (targets_atom == GDK_NONE)
11048     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
11049
11050   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
11051                          GDK_CURRENT_TIME);
11052 }
11053
11054 void
11055 create_selection_test (GtkWidget *widget)
11056 {
11057   static GtkWidget *window = NULL;
11058   GtkWidget *button;
11059   GtkWidget *vbox;
11060   GtkWidget *scrolled_win;
11061   GtkWidget *list;
11062   GtkWidget *label;
11063
11064   if (!window)
11065     {
11066       window = gtk_dialog_new ();
11067       
11068       gtk_window_set_screen (GTK_WINDOW (window),
11069                              gtk_widget_get_screen (widget));
11070
11071       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11072                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11073                           &window);
11074
11075       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
11076       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11077
11078       /* Create the list */
11079
11080       vbox = gtk_vbox_new (FALSE, 5);
11081       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11082       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
11083                           TRUE, TRUE, 0);
11084
11085       label = gtk_label_new ("Gets available targets for current selection");
11086       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11087
11088       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
11089       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
11090                                       GTK_POLICY_AUTOMATIC, 
11091                                       GTK_POLICY_AUTOMATIC);
11092       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
11093       gtk_widget_set_usize (scrolled_win, 100, 200);
11094
11095       list = gtk_list_new ();
11096       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
11097
11098       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
11099                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
11100
11101       /* .. And create some buttons */
11102       button = gtk_button_new_with_label ("Get Targets");
11103       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11104                           button, TRUE, TRUE, 0);
11105
11106       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11107                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
11108
11109       button = gtk_button_new_with_label ("Quit");
11110       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11111                           button, TRUE, TRUE, 0);
11112
11113       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11114                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11115                                  GTK_OBJECT (window));
11116     }
11117
11118   if (!GTK_WIDGET_VISIBLE (window))
11119     gtk_widget_show_all (window);
11120   else
11121     gtk_widget_destroy (window);
11122 }
11123
11124 /*
11125  * Gamma Curve
11126  */
11127
11128 void
11129 create_gamma_curve (GtkWidget *widget)
11130 {
11131   static GtkWidget *window = NULL, *curve;
11132   static int count = 0;
11133   gfloat vec[256];
11134   gint max;
11135   gint i;
11136   
11137   if (!window)
11138     {
11139       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11140       gtk_window_set_screen (GTK_WINDOW (window),
11141                              gtk_widget_get_screen (widget));
11142
11143       gtk_window_set_title (GTK_WINDOW (window), "test");
11144       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11145
11146       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11147                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11148                           &window);
11149
11150       curve = gtk_gamma_curve_new ();
11151       gtk_container_add (GTK_CONTAINER (window), curve);
11152       gtk_widget_show (curve);
11153     }
11154
11155   max = 127 + (count % 2)*128;
11156   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11157                        0, max, 0, max);
11158   for (i = 0; i < max; ++i)
11159     vec[i] = (127 / sqrt (max)) * sqrt (i);
11160   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11161                         max, vec);
11162
11163   if (!GTK_WIDGET_VISIBLE (window))
11164     gtk_widget_show (window);
11165   else if (count % 4 == 3)
11166     {
11167       gtk_widget_destroy (window);
11168       window = NULL;
11169     }
11170
11171   ++count;
11172 }
11173
11174 /*
11175  * Test scrolling
11176  */
11177
11178 static int scroll_test_pos = 0.0;
11179
11180 static gint
11181 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
11182                     GtkAdjustment *adj)
11183 {
11184   gint i,j;
11185   gint imin, imax, jmin, jmax;
11186   
11187   imin = (event->area.x) / 10;
11188   imax = (event->area.x + event->area.width + 9) / 10;
11189
11190   jmin = ((int)adj->value + event->area.y) / 10;
11191   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
11192
11193   gdk_window_clear_area (widget->window,
11194                          event->area.x, event->area.y,
11195                          event->area.width, event->area.height);
11196
11197   for (i=imin; i<imax; i++)
11198     for (j=jmin; j<jmax; j++)
11199       if ((i+j) % 2)
11200         gdk_draw_rectangle (widget->window, 
11201                             widget->style->black_gc,
11202                             TRUE,
11203                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
11204
11205   return TRUE;
11206 }
11207
11208 static gint
11209 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
11210                     GtkAdjustment *adj)
11211 {
11212   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
11213                                     -adj->page_increment / 2:
11214                                     adj->page_increment / 2);
11215   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
11216   gtk_adjustment_set_value (adj, new_value);  
11217   
11218   return TRUE;
11219 }
11220
11221 static void
11222 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
11223                        GtkAdjustment *adj)
11224 {
11225   adj->page_increment = 0.9 * widget->allocation.height;
11226   adj->page_size = widget->allocation.height;
11227
11228   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
11229 }
11230
11231 static void
11232 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
11233 {
11234   /* gint source_min = (int)adj->value - scroll_test_pos; */
11235   gint dy;
11236
11237   dy = scroll_test_pos - (int)adj->value;
11238   scroll_test_pos = adj->value;
11239
11240   if (!GTK_WIDGET_DRAWABLE (widget))
11241     return;
11242   gdk_window_scroll (widget->window, 0, dy);
11243   gdk_window_process_updates (widget->window, FALSE);
11244 }
11245
11246
11247 void
11248 create_scroll_test (GtkWidget *widget)
11249 {
11250   static GtkWidget *window = NULL;
11251   GtkWidget *hbox;
11252   GtkWidget *drawing_area;
11253   GtkWidget *scrollbar;
11254   GtkWidget *button;
11255   GtkAdjustment *adj;
11256   GdkGeometry geometry;
11257   GdkWindowHints geometry_mask;
11258
11259   if (!window)
11260     {
11261       window = gtk_dialog_new ();
11262
11263       gtk_window_set_screen (GTK_WINDOW (window),
11264                              gtk_widget_get_screen (widget));
11265
11266       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11267                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11268                           &window);
11269
11270       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
11271       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11272
11273       hbox = gtk_hbox_new (FALSE, 0);
11274       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
11275                           TRUE, TRUE, 0);
11276       gtk_widget_show (hbox);
11277
11278       drawing_area = gtk_drawing_area_new ();
11279       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
11280       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
11281       gtk_widget_show (drawing_area);
11282
11283       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
11284
11285       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
11286       scroll_test_pos = 0.0;
11287
11288       scrollbar = gtk_vscrollbar_new (adj);
11289       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
11290       gtk_widget_show (scrollbar);
11291
11292       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
11293                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
11294       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
11295                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
11296       gtk_signal_connect (GTK_OBJECT (drawing_area), "scroll_event",
11297                           GTK_SIGNAL_FUNC (scroll_test_scroll), adj);
11298       
11299       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
11300                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
11301                           drawing_area);
11302       
11303       /* .. And create some buttons */
11304
11305       button = gtk_button_new_with_label ("Quit");
11306       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11307                           button, TRUE, TRUE, 0);
11308
11309       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11310                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11311                                  GTK_OBJECT (window));
11312       gtk_widget_show (button);
11313
11314       /* Set up gridded geometry */
11315
11316       geometry_mask = GDK_HINT_MIN_SIZE | 
11317                        GDK_HINT_BASE_SIZE | 
11318                        GDK_HINT_RESIZE_INC;
11319
11320       geometry.min_width = 20;
11321       geometry.min_height = 20;
11322       geometry.base_width = 0;
11323       geometry.base_height = 0;
11324       geometry.width_inc = 10;
11325       geometry.height_inc = 10;
11326       
11327       gtk_window_set_geometry_hints (GTK_WINDOW (window),
11328                                drawing_area, &geometry, geometry_mask);
11329     }
11330
11331   if (!GTK_WIDGET_VISIBLE (window))
11332     gtk_widget_show (window);
11333   else
11334     gtk_widget_destroy (window);
11335 }
11336
11337 /*
11338  * Timeout Test
11339  */
11340
11341 static int timer = 0;
11342
11343 gint
11344 timeout_test (GtkWidget *label)
11345 {
11346   static int count = 0;
11347   static char buffer[32];
11348
11349   sprintf (buffer, "count: %d", ++count);
11350   gtk_label_set_text (GTK_LABEL (label), buffer);
11351
11352   return TRUE;
11353 }
11354
11355 void
11356 start_timeout_test (GtkWidget *widget,
11357                     GtkWidget *label)
11358 {
11359   if (!timer)
11360     {
11361       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
11362     }
11363 }
11364
11365 void
11366 stop_timeout_test (GtkWidget *widget,
11367                    gpointer   data)
11368 {
11369   if (timer)
11370     {
11371       gtk_timeout_remove (timer);
11372       timer = 0;
11373     }
11374 }
11375
11376 void
11377 destroy_timeout_test (GtkWidget  *widget,
11378                       GtkWidget **window)
11379 {
11380   stop_timeout_test (NULL, NULL);
11381
11382   *window = NULL;
11383 }
11384
11385 void
11386 create_timeout_test (GtkWidget *widget)
11387 {
11388   static GtkWidget *window = NULL;
11389   GtkWidget *button;
11390   GtkWidget *label;
11391
11392   if (!window)
11393     {
11394       window = gtk_dialog_new ();
11395
11396       gtk_window_set_screen (GTK_WINDOW (window),
11397                              gtk_widget_get_screen (widget));
11398
11399       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11400                           GTK_SIGNAL_FUNC(destroy_timeout_test),
11401                           &window);
11402
11403       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
11404       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11405
11406       label = gtk_label_new ("count: 0");
11407       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11408       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11409                           label, TRUE, TRUE, 0);
11410       gtk_widget_show (label);
11411
11412       button = gtk_button_new_with_label ("close");
11413       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11414                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11415                                  GTK_OBJECT (window));
11416       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11417       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11418                           button, TRUE, TRUE, 0);
11419       gtk_widget_grab_default (button);
11420       gtk_widget_show (button);
11421
11422       button = gtk_button_new_with_label ("start");
11423       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11424                           GTK_SIGNAL_FUNC(start_timeout_test),
11425                           label);
11426       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11427       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11428                           button, TRUE, TRUE, 0);
11429       gtk_widget_show (button);
11430
11431       button = gtk_button_new_with_label ("stop");
11432       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11433                           GTK_SIGNAL_FUNC(stop_timeout_test),
11434                           NULL);
11435       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11436       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11437                           button, TRUE, TRUE, 0);
11438       gtk_widget_show (button);
11439     }
11440
11441   if (!GTK_WIDGET_VISIBLE (window))
11442     gtk_widget_show (window);
11443   else
11444     gtk_widget_destroy (window);
11445 }
11446
11447 /*
11448  * Idle Test
11449  */
11450
11451 static int idle_id = 0;
11452
11453 static gint
11454 idle_test (GtkWidget *label)
11455 {
11456   static int count = 0;
11457   static char buffer[32];
11458
11459   sprintf (buffer, "count: %d", ++count);
11460   gtk_label_set_text (GTK_LABEL (label), buffer);
11461
11462   return TRUE;
11463 }
11464
11465 static void
11466 start_idle_test (GtkWidget *widget,
11467                  GtkWidget *label)
11468 {
11469   if (!idle_id)
11470     {
11471       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
11472     }
11473 }
11474
11475 static void
11476 stop_idle_test (GtkWidget *widget,
11477                 gpointer   data)
11478 {
11479   if (idle_id)
11480     {
11481       gtk_idle_remove (idle_id);
11482       idle_id = 0;
11483     }
11484 }
11485
11486 static void
11487 destroy_idle_test (GtkWidget  *widget,
11488                    GtkWidget **window)
11489 {
11490   stop_idle_test (NULL, NULL);
11491
11492   *window = NULL;
11493 }
11494
11495 static void
11496 toggle_idle_container (GtkObject *button,
11497                        GtkContainer *container)
11498 {
11499   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (gtk_object_get_user_data (button)));
11500 }
11501
11502 static void
11503 create_idle_test (GtkWidget *widget)
11504 {
11505   static GtkWidget *window = NULL;
11506   GtkWidget *button;
11507   GtkWidget *label;
11508   GtkWidget *container;
11509
11510   if (!window)
11511     {
11512       GtkWidget *button2;
11513       GtkWidget *frame;
11514       GtkWidget *box;
11515
11516       window = gtk_dialog_new ();
11517
11518       gtk_window_set_screen (GTK_WINDOW (window),
11519                              gtk_widget_get_screen (widget));
11520
11521       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11522                           GTK_SIGNAL_FUNC(destroy_idle_test),
11523                           &window);
11524
11525       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
11526       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11527
11528       label = gtk_label_new ("count: 0");
11529       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11530       gtk_widget_show (label);
11531       
11532       container =
11533         gtk_widget_new (GTK_TYPE_HBOX,
11534                         "visible", TRUE,
11535                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
11536                          * "GtkWidget::visible", TRUE,
11537                          */
11538                          "child", label,
11539                         /* NULL), */
11540                         NULL);
11541       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11542                           container, TRUE, TRUE, 0);
11543
11544       frame =
11545         gtk_widget_new (GTK_TYPE_FRAME,
11546                         "border_width", 5,
11547                         "label", "Label Container",
11548                         "visible", TRUE,
11549                         "parent", GTK_DIALOG (window)->vbox,
11550                         NULL);
11551       box =
11552         gtk_widget_new (GTK_TYPE_VBOX,
11553                         "visible", TRUE,
11554                         "parent", frame,
11555                         NULL);
11556       button =
11557         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11558                                           "label", "Resize-Parent",
11559                                           "user_data", (void*)GTK_RESIZE_PARENT,
11560                                           "visible", TRUE,
11561                                           "parent", box,
11562                                           NULL),
11563                           "signal::clicked", toggle_idle_container, container,
11564                           NULL);
11565       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11566                                "label", "Resize-Queue",
11567                                "user_data", (void*)GTK_RESIZE_QUEUE,
11568                                "group", button,
11569                                "visible", TRUE,
11570                                "parent", box,
11571                                NULL);
11572       g_object_connect (button,
11573                         "signal::clicked", toggle_idle_container, container,
11574                         NULL);
11575       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11576                                 "label", "Resize-Immediate",
11577                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
11578                                 NULL);
11579       g_object_connect (button2,
11580                         "signal::clicked", toggle_idle_container, container,
11581                         NULL);
11582       g_object_set (button2,
11583                     "group", button,
11584                     "visible", TRUE,
11585                     "parent", box,
11586                     NULL);
11587
11588       button = gtk_button_new_with_label ("close");
11589       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11590                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11591                                  GTK_OBJECT (window));
11592       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11593       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11594                           button, TRUE, TRUE, 0);
11595       gtk_widget_grab_default (button);
11596       gtk_widget_show (button);
11597
11598       button = gtk_button_new_with_label ("start");
11599       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11600                           GTK_SIGNAL_FUNC(start_idle_test),
11601                           label);
11602       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11603       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11604                           button, TRUE, TRUE, 0);
11605       gtk_widget_show (button);
11606
11607       button = gtk_button_new_with_label ("stop");
11608       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11609                           GTK_SIGNAL_FUNC(stop_idle_test),
11610                           NULL);
11611       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11612       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11613                           button, TRUE, TRUE, 0);
11614       gtk_widget_show (button);
11615     }
11616
11617   if (!GTK_WIDGET_VISIBLE (window))
11618     gtk_widget_show (window);
11619   else
11620     gtk_widget_destroy (window);
11621 }
11622
11623 /*
11624  * rc file test
11625  */
11626
11627 void
11628 reload_all_rc_files (void)
11629 {
11630   static GdkAtom atom_rcfiles = GDK_NONE;
11631
11632   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
11633   int i;
11634   
11635   if (!atom_rcfiles)
11636     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
11637
11638   for(i = 0; i < 5; i++)
11639     send_event->client.data.l[i] = 0;
11640   send_event->client.data_format = 32;
11641   send_event->client.message_type = atom_rcfiles;
11642   gdk_event_send_clientmessage_toall (send_event);
11643
11644   gdk_event_free (send_event);
11645 }
11646
11647 void
11648 create_rc_file (GtkWidget *widget)
11649 {
11650   static GtkWidget *window = NULL;
11651   GtkWidget *button;
11652   GtkWidget *frame;
11653   GtkWidget *vbox;
11654   GtkWidget *label;
11655
11656   if (!window)
11657     {
11658       window = gtk_dialog_new ();
11659
11660       gtk_window_set_screen (GTK_WINDOW (window),
11661                              gtk_widget_get_screen (widget));
11662
11663       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11664                           GTK_SIGNAL_FUNC(destroy_idle_test),
11665                           &window);
11666
11667       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
11668       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
11669
11670       vbox = gtk_vbox_new (FALSE, 0);
11671       gtk_container_add (GTK_CONTAINER (frame), vbox);
11672       
11673       label = gtk_label_new ("This label should be red");
11674       gtk_widget_set_name (label, "testgtk-red-label");
11675       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11676
11677       label = gtk_label_new ("This label should be green");
11678       gtk_widget_set_name (label, "testgtk-green-label");
11679       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11680
11681       label = gtk_label_new ("This label should be blue");
11682       gtk_widget_set_name (label, "testgtk-blue-label");
11683       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11684
11685       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
11686       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11687
11688       button = gtk_button_new_with_label ("Reload");
11689       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11690                           GTK_SIGNAL_FUNC(gtk_rc_reparse_all), NULL);
11691       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11692       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11693                           button, TRUE, TRUE, 0);
11694       gtk_widget_grab_default (button);
11695
11696       button = gtk_button_new_with_label ("Reload All");
11697       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11698                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
11699       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11700       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11701                           button, TRUE, TRUE, 0);
11702
11703       button = gtk_button_new_with_label ("Close");
11704       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11705                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11706                                  GTK_OBJECT (window));
11707       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11708       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11709                           button, TRUE, TRUE, 0);
11710     }
11711
11712   if (!GTK_WIDGET_VISIBLE (window))
11713     gtk_widget_show_all (window);
11714   else
11715     gtk_widget_destroy (window);
11716 }
11717
11718 /*
11719  * Test of recursive mainloop
11720  */
11721
11722 void
11723 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
11724 {
11725   *window = NULL;
11726   gtk_main_quit ();
11727 }
11728
11729 void
11730 create_mainloop (GtkWidget *widget)
11731 {
11732   static GtkWidget *window = NULL;
11733   GtkWidget *label;
11734   GtkWidget *button;
11735
11736   if (!window)
11737     {
11738       window = gtk_dialog_new ();
11739
11740       gtk_window_set_screen (GTK_WINDOW (window),
11741                              gtk_widget_get_screen (widget));
11742
11743       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
11744
11745       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11746                           GTK_SIGNAL_FUNC(mainloop_destroyed),
11747                           &window);
11748
11749       label = gtk_label_new ("In recursive main loop...");
11750       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
11751
11752       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
11753                           TRUE, TRUE, 0);
11754       gtk_widget_show (label);
11755
11756       button = gtk_button_new_with_label ("Leave");
11757       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
11758                           FALSE, TRUE, 0);
11759
11760       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11761                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11762                                  GTK_OBJECT (window));
11763
11764       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11765       gtk_widget_grab_default (button);
11766
11767       gtk_widget_show (button);
11768     }
11769
11770   if (!GTK_WIDGET_VISIBLE (window))
11771     {
11772       gtk_widget_show (window);
11773
11774       g_print ("create_mainloop: start\n");
11775       gtk_main ();
11776       g_print ("create_mainloop: done\n");
11777     }
11778   else
11779     gtk_widget_destroy (window);
11780 }
11781
11782 gboolean
11783 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
11784 {
11785   GtkLayout *layout;
11786
11787   gint i,j;
11788   gint imin, imax, jmin, jmax;
11789
11790   layout = GTK_LAYOUT (widget);
11791
11792   if (event->window != layout->bin_window)
11793     return FALSE;
11794   
11795   imin = (event->area.x) / 10;
11796   imax = (event->area.x + event->area.width + 9) / 10;
11797
11798   jmin = (event->area.y) / 10;
11799   jmax = (event->area.y + event->area.height + 9) / 10;
11800
11801   for (i=imin; i<imax; i++)
11802     for (j=jmin; j<jmax; j++)
11803       if ((i+j) % 2)
11804         gdk_draw_rectangle (layout->bin_window,
11805                             widget->style->black_gc,
11806                             TRUE,
11807                             10*i, 10*j, 
11808                             1+i%10, 1+j%10);
11809   
11810   return FALSE;
11811 }
11812
11813 void create_layout (GtkWidget *widget)
11814 {
11815   static GtkWidget *window = NULL;
11816   GtkWidget *layout;
11817   GtkWidget *scrolledwindow;
11818   GtkWidget *button;
11819
11820   if (!window)
11821     {
11822       gchar buf[16];
11823
11824       gint i, j;
11825       
11826       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11827       gtk_window_set_screen (GTK_WINDOW (window),
11828                              gtk_widget_get_screen (widget));
11829
11830       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11831                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11832                           &window);
11833
11834       gtk_window_set_title (GTK_WINDOW (window), "Layout");
11835       gtk_widget_set_usize (window, 200, 200);
11836
11837       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
11838       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
11839                                            GTK_SHADOW_IN);
11840       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
11841                                          GTK_CORNER_TOP_RIGHT);
11842
11843       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
11844       
11845       layout = gtk_layout_new (NULL, NULL);
11846       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
11847
11848       /* We set step sizes here since GtkLayout does not set
11849        * them itself.
11850        */
11851       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
11852       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
11853       
11854       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
11855       gtk_signal_connect (GTK_OBJECT (layout), "expose_event",
11856                           GTK_SIGNAL_FUNC (layout_expose_handler), NULL);
11857       
11858       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
11859       
11860       for (i=0 ; i < 16 ; i++)
11861         for (j=0 ; j < 16 ; j++)
11862           {
11863             sprintf(buf, "Button %d, %d", i, j);
11864             if ((i + j) % 2)
11865               button = gtk_button_new_with_label (buf);
11866             else
11867               button = gtk_label_new (buf);
11868
11869             gtk_layout_put (GTK_LAYOUT (layout), button,
11870                             j*100, i*100);
11871           }
11872
11873       for (i=16; i < 1280; i++)
11874         {
11875           sprintf(buf, "Button %d, %d", i, 0);
11876           if (i % 2)
11877             button = gtk_button_new_with_label (buf);
11878           else
11879             button = gtk_label_new (buf);
11880
11881           gtk_layout_put (GTK_LAYOUT (layout), button,
11882                           0, i*100);
11883         }
11884     }
11885
11886   if (!GTK_WIDGET_VISIBLE (window))
11887     gtk_widget_show_all (window);
11888   else
11889     gtk_widget_destroy (window);
11890 }
11891
11892 void
11893 create_styles (GtkWidget *widget)
11894 {
11895   static GtkWidget *window = NULL;
11896   GtkWidget *label;
11897   GtkWidget *button;
11898   GtkWidget *entry;
11899   GtkWidget *vbox;
11900   static GdkColor red =    { 0, 0xffff, 0,      0      };
11901   static GdkColor green =  { 0, 0,      0xffff, 0      };
11902   static GdkColor blue =   { 0, 0,      0,      0xffff };
11903   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
11904   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
11905   PangoFontDescription *font_desc;
11906
11907   GtkRcStyle *rc_style;
11908
11909   if (!window)
11910     {
11911       window = gtk_dialog_new ();
11912       gtk_window_set_screen (GTK_WINDOW (window),
11913                              gtk_widget_get_screen (widget));
11914      
11915       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11916                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11917                           &window);
11918
11919       
11920       button = gtk_button_new_with_label ("Close");
11921       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11922                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11923                                  GTK_OBJECT (window));
11924       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11925       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11926                           button, TRUE, TRUE, 0);
11927       gtk_widget_show (button);
11928
11929       vbox = gtk_vbox_new (FALSE, 5);
11930       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11931       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
11932       
11933       label = gtk_label_new ("Font:");
11934       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11935       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11936
11937       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
11938
11939       button = gtk_button_new_with_label ("Some Text");
11940       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
11941       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11942
11943       label = gtk_label_new ("Foreground:");
11944       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11945       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11946
11947       button = gtk_button_new_with_label ("Some Text");
11948       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
11949       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11950
11951       label = gtk_label_new ("Background:");
11952       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11953       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11954
11955       button = gtk_button_new_with_label ("Some Text");
11956       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
11957       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11958
11959       label = gtk_label_new ("Text:");
11960       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11961       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11962
11963       entry = gtk_entry_new ();
11964       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11965       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
11966       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11967
11968       label = gtk_label_new ("Base:");
11969       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11970       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11971
11972       entry = gtk_entry_new ();
11973       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11974       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
11975       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11976
11977       label = gtk_label_new ("Multiple:");
11978       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11979       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11980
11981       button = gtk_button_new_with_label ("Some Text");
11982
11983       rc_style = gtk_rc_style_new ();
11984
11985       rc_style->font_desc = pango_font_description_copy (font_desc);
11986       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
11987       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
11988       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
11989       rc_style->fg[GTK_STATE_NORMAL] = yellow;
11990       rc_style->bg[GTK_STATE_NORMAL] = blue;
11991       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
11992       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
11993       rc_style->fg[GTK_STATE_ACTIVE] = red;
11994       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
11995       rc_style->xthickness = 5;
11996       rc_style->ythickness = 5;
11997
11998       gtk_widget_modify_style (button, rc_style);
11999       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
12000
12001       g_object_unref (G_OBJECT (rc_style));
12002       
12003       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12004     }
12005   
12006   if (!GTK_WIDGET_VISIBLE (window))
12007     gtk_widget_show_all (window);
12008   else
12009     gtk_widget_destroy (window);
12010 }
12011
12012 /*
12013  * Main Window and Exit
12014  */
12015
12016 void
12017 do_exit (GtkWidget *widget, GtkWidget *window)
12018 {
12019   gtk_widget_destroy (window);
12020   gtk_main_quit ();
12021 }
12022
12023 struct {
12024   char *label;
12025   void (*func) ();
12026   gboolean do_not_benchmark;
12027 } buttons[] =
12028 {
12029   { "big windows", create_big_windows },
12030   { "button box", create_button_box },
12031   { "buttons", create_buttons },
12032   { "check buttons", create_check_buttons },
12033   { "clist", create_clist},
12034   { "color selection", create_color_selection },
12035   { "ctree", create_ctree },
12036   { "cursors", create_cursors },
12037   { "dialog", create_dialog },
12038   { "display & screen", create_display_screen },
12039   { "entry", create_entry },
12040   { "event watcher", create_event_watcher },
12041   { "file selection", create_file_selection },
12042   { "flipping", create_flipping },
12043   { "focus", create_focus },
12044   { "font selection", create_font_selection },
12045   { "gamma curve", create_gamma_curve, TRUE },
12046   { "gridded geometry", create_gridded_geometry, TRUE },
12047   { "handle box", create_handle_box },
12048   { "image from drawable", create_get_image },
12049   { "image", create_image },
12050   { "item factory", create_item_factory },
12051   { "key lookup", create_key_lookup },
12052   { "labels", create_labels },
12053   { "layout", create_layout },
12054   { "list", create_list },
12055   { "menus", create_menus },
12056   { "message dialog", create_message_dialog },
12057   { "modal window", create_modal_window, TRUE },
12058   { "notebook", create_notebook },
12059   { "panes", create_panes },
12060   { "paned keyboard", create_paned_keyboard_navigation },
12061   { "pixmap", create_pixmap },
12062   { "preview color", create_color_preview, TRUE },
12063   { "preview gray", create_gray_preview, TRUE },
12064   { "progress bar", create_progress_bar },
12065   { "properties", create_properties },
12066   { "radio buttons", create_radio_buttons },
12067   { "range controls", create_range_controls },
12068   { "rc file", create_rc_file },
12069   { "reparent", create_reparent },
12070   { "rulers", create_rulers },
12071   { "saved position", create_saved_position },
12072   { "scrolled windows", create_scrolled_windows },
12073   { "shapes", create_shapes },
12074   { "size groups", create_size_groups },
12075   { "spinbutton", create_spins },
12076   { "statusbar", create_statusbar },
12077   { "styles", create_styles },
12078   { "test idle", create_idle_test },
12079   { "test mainloop", create_mainloop, TRUE },
12080   { "test scrolling", create_scroll_test },
12081   { "test selection", create_selection_test },
12082   { "test timeout", create_timeout_test },
12083   { "text", create_text },
12084   { "toggle buttons", create_toggle_buttons },
12085   { "toolbar", create_toolbar },
12086   { "tooltips", create_tooltips },
12087   { "tree", create_tree_mode_window},
12088   { "WM hints", create_wmhints },
12089   { "window sizing", create_window_sizing },
12090   { "window states", create_window_states }
12091 };
12092 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
12093
12094 void
12095 create_main_window (void)
12096 {
12097   GtkWidget *window;
12098   GtkWidget *box1;
12099   GtkWidget *box2;
12100   GtkWidget *scrolled_window;
12101   GtkWidget *button;
12102   GtkWidget *label;
12103   gchar buffer[64];
12104   GtkWidget *separator;
12105   GdkGeometry geometry;
12106   int i;
12107
12108   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12109   gtk_widget_set_name (window, "main window");
12110   gtk_widget_set_uposition (window, 20, 20);
12111   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
12112
12113   geometry.min_width = -1;
12114   geometry.min_height = -1;
12115   geometry.max_width = -1;
12116   geometry.max_height = G_MAXSHORT;
12117   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
12118                                  &geometry,
12119                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
12120
12121   gtk_signal_connect (GTK_OBJECT (window), "destroy",
12122                       GTK_SIGNAL_FUNC(gtk_main_quit),
12123                       NULL);
12124   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
12125                       GTK_SIGNAL_FUNC (gtk_false),
12126                       NULL);
12127
12128   box1 = gtk_vbox_new (FALSE, 0);
12129   gtk_container_add (GTK_CONTAINER (window), box1);
12130
12131   if (gtk_micro_version > 0)
12132     sprintf (buffer,
12133              "Gtk+ v%d.%d.%d",
12134              gtk_major_version,
12135              gtk_minor_version,
12136              gtk_micro_version);
12137   else
12138     sprintf (buffer,
12139              "Gtk+ v%d.%d",
12140              gtk_major_version,
12141              gtk_minor_version);
12142
12143   label = gtk_label_new (buffer);
12144   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
12145   gtk_widget_set_name (label, "testgtk-version-label");
12146
12147   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
12148   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
12149   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
12150                                   GTK_POLICY_NEVER, 
12151                                   GTK_POLICY_AUTOMATIC);
12152   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
12153
12154   box2 = gtk_vbox_new (FALSE, 0);
12155   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12156   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
12157   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
12158                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
12159   gtk_widget_show (box2);
12160
12161   for (i = 0; i < nbuttons; i++)
12162     {
12163       button = gtk_button_new_with_label (buttons[i].label);
12164       if (buttons[i].func)
12165         gtk_signal_connect (GTK_OBJECT (button), 
12166                             "clicked", 
12167                             GTK_SIGNAL_FUNC(buttons[i].func),
12168                             NULL);
12169       else
12170         gtk_widget_set_sensitive (button, FALSE);
12171       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12172     }
12173
12174   separator = gtk_hseparator_new ();
12175   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
12176
12177   box2 = gtk_vbox_new (FALSE, 10);
12178   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12179   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
12180
12181   button = gtk_button_new_with_mnemonic ("_Close");
12182   gtk_signal_connect (GTK_OBJECT (button), "clicked",
12183                       GTK_SIGNAL_FUNC (do_exit),
12184                       window);
12185   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12186   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12187   gtk_widget_grab_default (button);
12188
12189   gtk_widget_show_all (window);
12190 }
12191
12192 static void
12193 test_init ()
12194 {
12195   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
12196                    G_FILE_TEST_EXISTS))
12197     {
12198       putenv ("GDK_PIXBUF_MODULE_FILE=../gdk-pixbuf/gdk-pixbuf.loaders");
12199       putenv ("GTK_IM_MODULE_FILE=../modules/input/gtk.immodules");
12200     }
12201 }
12202
12203 static char *
12204 pad (const char *str, int to)
12205 {
12206   static char buf[256];
12207   int len = strlen (str);
12208   int i;
12209
12210   for (i = 0; i < to; i++)
12211     buf[i] = ' ';
12212
12213   buf[to] = '\0';
12214
12215   memcpy (buf, str, len);
12216
12217   return buf;
12218 }
12219
12220 static void
12221 bench_iteration (void (* fn) ())
12222 {
12223   fn (); /* on */
12224   while (g_main_iteration (FALSE));
12225   fn (); /* off */
12226   while (g_main_iteration (FALSE));
12227 }
12228
12229 void
12230 do_real_bench (void (* fn) (), char *name, int num)
12231 {
12232   GTimeVal tv0, tv1;
12233   double dt_first;
12234   double dt;
12235   int n;
12236   static gboolean printed_headers = FALSE;
12237
12238   if (!printed_headers) {
12239     g_print ("Test                 Iters      First      Other\n");
12240     g_print ("-------------------- ----- ---------- ----------\n");
12241     printed_headers = TRUE;
12242   }
12243
12244   g_get_current_time (&tv0);
12245   bench_iteration (fn); 
12246   g_get_current_time (&tv1);
12247
12248   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12249         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12250
12251   g_get_current_time (&tv0);
12252   for (n = 0; n < num - 1; n++)
12253     bench_iteration (fn); 
12254   g_get_current_time (&tv1);
12255   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12256         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12257
12258   g_print ("%s %5d ", pad (name, 20), num);
12259   if (num > 1)
12260     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
12261   else
12262     g_print ("%10.1f\n", dt_first);
12263 }
12264
12265 void
12266 do_bench (char* what, int num)
12267 {
12268   int i;
12269   void (* fn) ();
12270   fn = NULL;
12271
12272   if (g_strcasecmp (what, "ALL") == 0)
12273     {
12274       for (i = 0; i < nbuttons; i++)
12275         {
12276           if (!buttons[i].do_not_benchmark)
12277             do_real_bench (buttons[i].func, buttons[i].label, num);
12278         }
12279
12280       return;
12281     }
12282   else
12283     {
12284       for (i = 0; i < nbuttons; i++)
12285         {
12286           if (strcmp (buttons[i].label, what) == 0)
12287             {
12288               fn = buttons[i].func;
12289               break;
12290             }
12291         }
12292       
12293       if (!fn)
12294         g_print ("Can't bench: \"%s\" not found.\n", what);
12295       else
12296         do_real_bench (fn, buttons[i].label, num);
12297     }
12298 }
12299
12300 void 
12301 usage (void)
12302 {
12303   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
12304   exit (1);
12305 }
12306
12307 int
12308 main (int argc, char *argv[])
12309 {
12310   GtkBindingSet *binding_set;
12311   int i;
12312   gboolean done_benchmarks = FALSE;
12313
12314   srand (time (NULL));
12315
12316   test_init ();
12317
12318   /* Check to see if we are being run from the correct
12319    * directory.
12320    */
12321   if (file_exists ("testgtkrc"))
12322     gtk_rc_add_default_file ("testgtkrc");
12323
12324   gtk_init (&argc, &argv);
12325
12326   /*  benchmarking
12327    */
12328   for (i = 1; i < argc; i++)
12329     {
12330       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
12331         {
12332           int num = 1;
12333           char *nextarg;
12334           char *what;
12335           char *count;
12336           
12337           nextarg = strchr (argv[i], '=');
12338           if (nextarg)
12339             nextarg++;
12340           else
12341             {
12342               i++;
12343               if (i == argc)
12344                 usage ();
12345               nextarg = argv[i];
12346             }
12347
12348           count = strchr (nextarg, ':');
12349           if (count)
12350             {
12351               what = g_strndup (nextarg, count - nextarg);
12352               count++;
12353               num = atoi (count);
12354               if (num <= 0)
12355                 usage ();
12356             }
12357           else
12358             what = g_strdup (nextarg);
12359
12360           do_bench (what, num ? num : 1);
12361           done_benchmarks = TRUE;
12362         }
12363       else
12364         usage ();
12365     }
12366   if (done_benchmarks)
12367     return 0;
12368
12369   /* bindings test
12370    */
12371   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
12372   gtk_binding_entry_add_signal (binding_set,
12373                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
12374                                 "debug_msg",
12375                                 1,
12376                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
12377   
12378   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
12379    * changes
12380    */
12381
12382   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
12383                        "   fg[NORMAL] = \"#ff0000\"\n"
12384                        "   font = \"Sans 18\"\n"
12385                        "}\n"
12386                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
12387   
12388   create_main_window ();
12389
12390   gtk_main ();
12391
12392   if (1)
12393     {
12394       while (g_main_pending ())
12395         g_main_iteration (FALSE);
12396 #if 0
12397       sleep (1);
12398       while (g_main_pending ())
12399         g_main_iteration (FALSE);
12400 #endif
12401     }
12402   return 0;
12403 }