]> Pileus Git - ~andy/gtk/blob - tests/testgtk.c
Improve checks on public entry points, including, among other things
[~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_widget_show_all (options_hbox);
6831
6832       gtk_signal_connect (
6833         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
6834         "color_changed",
6835         GTK_SIGNAL_FUNC(color_selection_changed),
6836         window);
6837
6838       gtk_signal_connect (
6839         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
6840         "clicked",
6841         GTK_SIGNAL_FUNC(color_selection_ok),
6842         window);
6843
6844       gtk_signal_connect_object (
6845         GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
6846         "clicked",
6847         GTK_SIGNAL_FUNC(gtk_widget_destroy),
6848         GTK_OBJECT (window));
6849     }
6850
6851   if (!GTK_WIDGET_VISIBLE (window))
6852     gtk_widget_show (window);
6853   else
6854     gtk_widget_destroy (window);
6855 }
6856
6857 /*
6858  * GtkFileSelection
6859  */
6860
6861 void
6862 show_fileops (GtkWidget        *widget,
6863               GtkFileSelection *fs)
6864 {
6865   gboolean show_ops;
6866
6867   show_ops = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6868
6869   if (show_ops)
6870     gtk_file_selection_show_fileop_buttons (fs);
6871   else
6872     gtk_file_selection_hide_fileop_buttons (fs);
6873 }
6874
6875 void
6876 select_multiple (GtkWidget        *widget,
6877                  GtkFileSelection *fs)
6878 {
6879   gboolean select_multiple;
6880
6881   select_multiple = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6882   gtk_file_selection_set_select_multiple (fs, select_multiple);
6883 }
6884
6885 void
6886 file_selection_ok (GtkFileSelection *fs)
6887 {
6888   int i;
6889   gchar **selections;
6890
6891   selections = gtk_file_selection_get_selections (fs);
6892
6893   for (i = 0; selections[i] != NULL; i++)
6894     g_print ("%s\n", selections[i]);
6895
6896   g_strfreev (selections);
6897
6898   gtk_widget_destroy (GTK_WIDGET (fs));
6899 }
6900
6901 void
6902 create_file_selection (GtkWidget *widget)
6903 {
6904   static GtkWidget *window = NULL;
6905   GtkWidget *button;
6906
6907   if (!window)
6908     {
6909       window = gtk_file_selection_new ("file selection dialog");
6910       gtk_window_set_screen (GTK_WINDOW (window),
6911                              gtk_widget_get_screen (widget));
6912
6913       gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (window));
6914
6915       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
6916
6917       g_signal_connect (window, "destroy",
6918                         G_CALLBACK (gtk_widget_destroyed),
6919                         &window);
6920
6921       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button,
6922                                 "clicked",
6923                                 G_CALLBACK (file_selection_ok),
6924                                 window);
6925       g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button,
6926                                 "clicked",
6927                                 G_CALLBACK (gtk_widget_destroy),
6928                                 window);
6929       
6930       button = gtk_check_button_new_with_label ("Show Fileops");
6931       g_signal_connect (button, "toggled",
6932                         G_CALLBACK (show_fileops),
6933                         window);
6934       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6935                           button, FALSE, FALSE, 0);
6936       gtk_widget_show (button);
6937
6938       button = gtk_check_button_new_with_label ("Select Multiple");
6939       g_signal_connect (button, "clicked",
6940                         G_CALLBACK (select_multiple),
6941                         window);
6942       gtk_box_pack_start (GTK_BOX (GTK_FILE_SELECTION (window)->action_area), 
6943                           button, FALSE, FALSE, 0);
6944       gtk_widget_show (button);
6945     }
6946   
6947   if (!GTK_WIDGET_VISIBLE (window))
6948     gtk_widget_show (window);
6949   else
6950     gtk_widget_destroy (window);
6951 }
6952
6953 void
6954 flipping_toggled_cb (GtkWidget *widget, gpointer data)
6955 {
6956   int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
6957   int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
6958
6959   gtk_widget_set_default_direction (new_direction);
6960 }
6961
6962 void
6963 create_flipping (GtkWidget *widget)
6964 {
6965   static GtkWidget *window = NULL;
6966   GtkWidget *check_button, *button;
6967
6968   if (!window)
6969     {
6970       window = gtk_dialog_new ();
6971
6972       gtk_window_set_screen (GTK_WINDOW (window),
6973                              gtk_widget_get_screen (widget));
6974
6975       gtk_signal_connect (GTK_OBJECT (window), "destroy",
6976                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
6977                           &window);
6978
6979       gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
6980
6981       check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
6982       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
6983                           check_button, TRUE, TRUE, 0);
6984
6985       if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
6986         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
6987
6988       gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
6989                           GTK_SIGNAL_FUNC (flipping_toggled_cb), FALSE);
6990
6991       gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
6992       
6993       button = gtk_button_new_with_label ("Close");
6994       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
6995                                  GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window));
6996       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
6997                           button, TRUE, TRUE, 0);
6998     }
6999   
7000   if (!GTK_WIDGET_VISIBLE (window))
7001     gtk_widget_show_all (window);
7002   else
7003     gtk_widget_destroy (window);
7004 }
7005
7006 /*
7007  * Focus test
7008  */
7009
7010 static GtkWidget*
7011 make_focus_table (GList **list)
7012 {
7013   GtkWidget *table;
7014   gint i, j;
7015   
7016   table = gtk_table_new (5, 5, FALSE);
7017
7018   i = 0;
7019   j = 0;
7020
7021   while (i < 5)
7022     {
7023       j = 0;
7024       while (j < 5)
7025         {
7026           GtkWidget *widget;
7027           
7028           if ((i + j) % 2)
7029             widget = gtk_entry_new ();
7030           else
7031             widget = gtk_button_new_with_label ("Foo");
7032
7033           *list = g_list_prepend (*list, widget);
7034           
7035           gtk_table_attach (GTK_TABLE (table),
7036                             widget,
7037                             i, i + 1,
7038                             j, j + 1,
7039                             GTK_EXPAND | GTK_FILL,
7040                             GTK_EXPAND | GTK_FILL,
7041                             5, 5);
7042           
7043           ++j;
7044         }
7045
7046       ++i;
7047     }
7048
7049   *list = g_list_reverse (*list);
7050   
7051   return table;
7052 }
7053
7054 static void
7055 create_focus (GtkWidget *widget)
7056 {
7057   static GtkWidget *window = NULL;
7058   
7059   if (!window)
7060     {
7061       GtkWidget *table;
7062       GtkWidget *frame;
7063       GList *list = NULL;
7064       
7065       window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
7066                                             NULL, 0,
7067                                             GTK_STOCK_CLOSE,
7068                                             GTK_RESPONSE_NONE,
7069                                             NULL);
7070
7071       gtk_window_set_screen (GTK_WINDOW (window),
7072                              gtk_widget_get_screen (widget));
7073
7074       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7075                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7076                           &window);
7077
7078       gtk_signal_connect (GTK_OBJECT (window), "response",
7079                           GTK_SIGNAL_FUNC (gtk_widget_destroy),
7080                           NULL);
7081       
7082       gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
7083
7084       frame = gtk_frame_new ("Weird tab focus chain");
7085
7086       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7087                           frame, TRUE, TRUE, 0);
7088       
7089       table = make_focus_table (&list);
7090
7091       gtk_container_add (GTK_CONTAINER (frame), table);
7092
7093       gtk_container_set_focus_chain (GTK_CONTAINER (table),
7094                                      list);
7095
7096       g_list_free (list);
7097       
7098       frame = gtk_frame_new ("Default tab focus chain");
7099
7100       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
7101                           frame, TRUE, TRUE, 0);
7102
7103       list = NULL;
7104       table = make_focus_table (&list);
7105
7106       g_list_free (list);
7107       
7108       gtk_container_add (GTK_CONTAINER (frame), table);      
7109     }
7110   
7111   if (!GTK_WIDGET_VISIBLE (window))
7112     gtk_widget_show_all (window);
7113   else
7114     gtk_widget_destroy (window);
7115 }
7116
7117 /*
7118  * GtkFontSelection
7119  */
7120
7121 void
7122 font_selection_ok (GtkWidget              *w,
7123                    GtkFontSelectionDialog *fs)
7124 {
7125   gchar *s = gtk_font_selection_dialog_get_font_name (fs);
7126
7127   g_print ("%s\n", s);
7128   g_free (s);
7129   gtk_widget_destroy (GTK_WIDGET (fs));
7130 }
7131
7132 void
7133 create_font_selection (GtkWidget *widget)
7134 {
7135   static GtkWidget *window = NULL;
7136
7137   if (!window)
7138     {
7139       window = gtk_font_selection_dialog_new ("Font Selection Dialog");
7140       
7141       gtk_window_set_screen (GTK_WINDOW (window),
7142                              gtk_widget_get_screen (widget));
7143
7144       gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
7145
7146       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7147                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7148                           &window);
7149
7150       gtk_signal_connect (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->ok_button),
7151                           "clicked", GTK_SIGNAL_FUNC(font_selection_ok),
7152                           GTK_FONT_SELECTION_DIALOG (window));
7153       gtk_signal_connect_object (GTK_OBJECT (GTK_FONT_SELECTION_DIALOG (window)->cancel_button),
7154                                  "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
7155                                  GTK_OBJECT (window));
7156     }
7157   
7158   if (!GTK_WIDGET_VISIBLE (window))
7159     gtk_widget_show (window);
7160   else
7161     gtk_widget_destroy (window);
7162 }
7163
7164 /*
7165  * GtkDialog
7166  */
7167
7168 static GtkWidget *dialog_window = NULL;
7169
7170 static void
7171 label_toggle (GtkWidget  *widget,
7172               GtkWidget **label)
7173 {
7174   if (!(*label))
7175     {
7176       *label = gtk_label_new ("Dialog Test");
7177       gtk_signal_connect (GTK_OBJECT (*label),
7178                           "destroy",
7179                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7180                           label);
7181       gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
7182       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7183                           *label, TRUE, TRUE, 0);
7184       gtk_widget_show (*label);
7185     }
7186   else
7187     gtk_widget_destroy (*label);
7188 }
7189
7190 #define RESPONSE_TOGGLE_SEPARATOR 1
7191
7192 static void
7193 print_response (GtkWidget *dialog,
7194                 gint       response_id,
7195                 gpointer   data)
7196 {
7197   g_print ("response signal received (%d)\n", response_id);
7198
7199   if (response_id == RESPONSE_TOGGLE_SEPARATOR)
7200     {
7201       gtk_dialog_set_has_separator (GTK_DIALOG (dialog),
7202                                     !gtk_dialog_get_has_separator (GTK_DIALOG (dialog)));
7203     }
7204 }
7205
7206 static void
7207 create_dialog (GtkWidget *widget)
7208 {
7209   static GtkWidget *label;
7210   GtkWidget *button;
7211
7212   if (!dialog_window)
7213     {
7214       /* This is a terrible example; it's much simpler to create
7215        * dialogs than this. Don't use testgtk for example code,
7216        * use gtk-demo ;-)
7217        */
7218       
7219       dialog_window = gtk_dialog_new ();
7220       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7221                              gtk_widget_get_screen (widget));
7222
7223       gtk_signal_connect (GTK_OBJECT (dialog_window),
7224                           "response",
7225                           GTK_SIGNAL_FUNC (print_response),
7226                           NULL);
7227       
7228       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
7229                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7230                           &dialog_window);
7231
7232       gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
7233       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7234
7235       button = gtk_button_new_with_label ("OK");
7236       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7237       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
7238                           button, TRUE, TRUE, 0);
7239       gtk_widget_grab_default (button);
7240       gtk_widget_show (button);
7241
7242       button = gtk_button_new_with_label ("Toggle");
7243       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7244                           GTK_SIGNAL_FUNC (label_toggle),
7245                           &label);
7246       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7247       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7248                           button, TRUE, TRUE, 0);
7249       gtk_widget_show (button);
7250
7251       label = NULL;
7252       
7253       button = gtk_button_new_with_label ("Separator");
7254
7255       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7256
7257       gtk_dialog_add_action_widget (GTK_DIALOG (dialog_window),
7258                                     button,
7259                                     RESPONSE_TOGGLE_SEPARATOR);
7260       gtk_widget_show (button);
7261     }
7262
7263   if (!GTK_WIDGET_VISIBLE (dialog_window))
7264     gtk_widget_show (dialog_window);
7265   else
7266     gtk_widget_destroy (dialog_window);
7267 }
7268
7269 /* Display & Screen test 
7270  */
7271
7272 typedef struct 
7273
7274   GtkEntry *entry;
7275   GtkWidget *radio_dpy;
7276   GtkWidget *toplevel; 
7277   GtkWidget *dialog_window;
7278   GList *valid_display_list;
7279 } ScreenDisplaySelection;
7280
7281 static gint
7282 display_name_cmp (gconstpointer a,
7283                   gconstpointer b)
7284 {
7285   return g_ascii_strcasecmp (a,b);
7286 }
7287
7288 static void
7289 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
7290 {
7291   char *display_name;
7292   GdkDisplay *display = gtk_widget_get_display (widget);
7293   GtkWidget *dialog;
7294   GdkScreen *new_screen = NULL;
7295   GdkScreen *current_screen = gtk_widget_get_screen (widget);
7296   
7297   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->radio_dpy)))
7298     {
7299       display_name = g_strdup (gtk_entry_get_text (data->entry));
7300       display = gdk_display_open (display_name);
7301       
7302       if (!display)
7303         {
7304           dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
7305                                            GTK_DIALOG_DESTROY_WITH_PARENT,
7306                                            GTK_MESSAGE_ERROR,
7307                                            GTK_BUTTONS_OK,
7308                                            "The display :\n%s\ncannot be opened",
7309                                            display_name);
7310           gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
7311           gtk_widget_show (dialog);
7312           g_signal_connect (G_OBJECT (dialog), "response",
7313                             G_CALLBACK (gtk_widget_destroy),
7314                             NULL);
7315         }
7316       else
7317         {
7318           if (!g_list_find_custom (data->valid_display_list, 
7319                                    display_name,
7320                                    display_name_cmp))
7321             data->valid_display_list = g_list_append (data->valid_display_list,
7322                                                       display_name);
7323           
7324           new_screen = gdk_display_get_default_screen (display);
7325         }
7326     }
7327   else
7328     {
7329       gint number_of_screens = gdk_display_get_n_screens (display);
7330       gint screen_num = gdk_screen_get_number (current_screen);
7331       if ((screen_num +1) < number_of_screens)
7332         new_screen = gdk_display_get_screen (display, screen_num + 1);
7333       else
7334         new_screen = gdk_display_get_screen (display, 0);
7335     }
7336   
7337   if (new_screen) 
7338     {
7339       gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
7340       gtk_widget_destroy (data->dialog_window);
7341     }
7342 }
7343
7344 void
7345 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
7346 {
7347   gtk_widget_destroy (data);
7348 }
7349
7350 void
7351 create_display_screen (GtkWidget *widget)
7352 {
7353   GtkWidget *table, *frame, *window, *combo_dpy, *vbox;
7354   GtkWidget *radio_dpy, *radio_scr, *applyb, *cancelb;
7355   GtkWidget *bbox;
7356   ScreenDisplaySelection *scr_dpy_data;
7357   GdkScreen *screen = gtk_widget_get_screen (widget);
7358   static GList *valid_display_list = NULL;
7359   
7360   GdkDisplay *display = gdk_screen_get_display (screen);
7361
7362   window = gtk_widget_new (gtk_window_get_type (),
7363                            "screen", screen,
7364                            "user_data", NULL,
7365                            "type", GTK_WINDOW_TOPLEVEL,
7366                            "title",
7367                            "Screen or Display selection",
7368                            "border_width", 10, NULL);
7369   g_signal_connect (G_OBJECT (window), "destroy", 
7370                     G_CALLBACK (gtk_widget_destroy), NULL);
7371
7372   vbox = gtk_vbox_new (FALSE, 3);
7373   gtk_container_add (GTK_CONTAINER (window), vbox);
7374   
7375   frame = gtk_frame_new ("Select screen or display");
7376   gtk_container_add (GTK_CONTAINER (vbox), frame);
7377   
7378   table = gtk_table_new (2, 2, TRUE);
7379   gtk_table_set_row_spacings (GTK_TABLE (table), 3);
7380   gtk_table_set_col_spacings (GTK_TABLE (table), 3);
7381
7382   gtk_container_add (GTK_CONTAINER (frame), table);
7383
7384   radio_dpy = gtk_radio_button_new_with_label (NULL, "move to another X display");
7385   if (gdk_display_get_n_screens(display) > 1)
7386     radio_scr = gtk_radio_button_new_with_label 
7387     (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), "move to next screen");
7388   else
7389     {    
7390       radio_scr = gtk_radio_button_new_with_label 
7391         (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_dpy)), 
7392          "only one screen on the current display");
7393       gtk_widget_set_sensitive (radio_scr, FALSE);
7394     }
7395   combo_dpy = gtk_combo_new ();
7396   if (!valid_display_list)
7397     valid_display_list = g_list_append (valid_display_list, "diabolo:0.0");
7398     
7399   gtk_combo_set_popdown_strings (GTK_COMBO (combo_dpy), valid_display_list);
7400     
7401   gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo_dpy)->entry), 
7402                       "<hostname>:<X Server Num>.<Screen Num>");
7403
7404   gtk_table_attach_defaults (GTK_TABLE (table), radio_dpy, 0, 1, 0, 1);
7405   gtk_table_attach_defaults (GTK_TABLE (table), radio_scr, 0, 1, 1, 2);
7406   gtk_table_attach_defaults (GTK_TABLE (table), combo_dpy, 1, 2, 0, 1);
7407
7408   bbox = gtk_hbutton_box_new ();
7409   applyb = gtk_button_new_from_stock (GTK_STOCK_APPLY);
7410   cancelb = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
7411   
7412   gtk_container_add (GTK_CONTAINER (vbox), bbox);
7413
7414   gtk_container_add (GTK_CONTAINER (bbox), applyb);
7415   gtk_container_add (GTK_CONTAINER (bbox), cancelb);
7416
7417   scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
7418
7419   scr_dpy_data->entry = GTK_ENTRY (GTK_COMBO (combo_dpy)->entry);
7420   scr_dpy_data->radio_dpy = radio_dpy;
7421   scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
7422   scr_dpy_data->dialog_window = window;
7423   scr_dpy_data->valid_display_list = valid_display_list;
7424
7425   g_signal_connect (G_OBJECT (cancelb), "clicked", 
7426                     G_CALLBACK (screen_display_destroy_diag), G_OBJECT (window));
7427   g_signal_connect (G_OBJECT (applyb), "clicked", 
7428                     G_CALLBACK (screen_display_check), scr_dpy_data);
7429   gtk_widget_show_all (window);
7430 }
7431
7432 /* Event Watcher
7433  */
7434 static gboolean event_watcher_enter_id = 0;
7435 static gboolean event_watcher_leave_id = 0;
7436
7437 static gboolean
7438 event_watcher (GSignalInvocationHint *ihint,
7439                guint                  n_param_values,
7440                const GValue          *param_values,
7441                gpointer               data)
7442 {
7443   g_print ("Watch: \"%s\" emitted for %s\n",
7444            gtk_signal_name (ihint->signal_id),
7445            gtk_type_name (GTK_OBJECT_TYPE (g_value_get_object (param_values + 0))));
7446
7447   return TRUE;
7448 }
7449
7450 static void
7451 event_watcher_down (void)
7452 {
7453   if (event_watcher_enter_id)
7454     {
7455       guint signal_id;
7456
7457       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7458       g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
7459       event_watcher_enter_id = 0;
7460       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7461       g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
7462       event_watcher_leave_id = 0;
7463     }
7464 }
7465
7466 static void
7467 event_watcher_toggle (void)
7468 {
7469   if (event_watcher_enter_id)
7470     event_watcher_down ();
7471   else
7472     {
7473       guint signal_id;
7474
7475       signal_id = gtk_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
7476       event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7477       signal_id = gtk_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
7478       event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
7479     }
7480 }
7481
7482 static void
7483 create_event_watcher (GtkWidget *widget)
7484 {
7485   GtkWidget *button;
7486
7487   if (!dialog_window)
7488     {
7489       dialog_window = gtk_dialog_new ();
7490       gtk_window_set_screen (GTK_WINDOW (dialog_window),
7491                              gtk_widget_get_screen (widget));
7492
7493       gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
7494                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
7495                           &dialog_window);
7496       gtk_signal_connect (GTK_OBJECT (dialog_window),
7497                           "destroy",
7498                           GTK_SIGNAL_FUNC (event_watcher_down),
7499                           NULL);
7500
7501       gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
7502       gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
7503       gtk_widget_set_usize (dialog_window, 200, 110);
7504
7505       button = gtk_toggle_button_new_with_label ("Activate Watch");
7506       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7507                           GTK_SIGNAL_FUNC (event_watcher_toggle),
7508                           NULL);
7509       gtk_container_set_border_width (GTK_CONTAINER (button), 10);
7510       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
7511                           button, TRUE, TRUE, 0);
7512       gtk_widget_show (button);
7513
7514       button = gtk_button_new_with_label ("Close");
7515       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7516                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
7517                                  (GtkObject*) dialog_window);
7518       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7519       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
7520                           button, TRUE, TRUE, 0);
7521       gtk_widget_grab_default (button);
7522       gtk_widget_show (button);
7523     }
7524
7525   if (!GTK_WIDGET_VISIBLE (dialog_window))
7526     gtk_widget_show (dialog_window);
7527   else
7528     gtk_widget_destroy (dialog_window);
7529 }
7530
7531 /*
7532  * GtkRange
7533  */
7534
7535 static gchar*
7536 reformat_value (GtkScale *scale,
7537                 gdouble   value)
7538 {
7539   return g_strdup_printf ("-->%0.*g<--",
7540                           gtk_scale_get_digits (scale), value);
7541 }
7542
7543 static void
7544 create_range_controls (GtkWidget *widget)
7545 {
7546   static GtkWidget *window = NULL;
7547   GtkWidget *box1;
7548   GtkWidget *box2;
7549   GtkWidget *button;
7550   GtkWidget *scrollbar;
7551   GtkWidget *scale;
7552   GtkWidget *separator;
7553   GtkObject *adjustment;
7554   GtkWidget *hbox;
7555
7556   if (!window)
7557     {
7558       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7559
7560       gtk_window_set_screen (GTK_WINDOW (window),
7561                              gtk_widget_get_screen (widget));
7562
7563       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7564                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7565                           &window);
7566
7567       gtk_window_set_title (GTK_WINDOW (window), "range controls");
7568       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7569
7570
7571       box1 = gtk_vbox_new (FALSE, 0);
7572       gtk_container_add (GTK_CONTAINER (window), box1);
7573       gtk_widget_show (box1);
7574
7575
7576       box2 = gtk_vbox_new (FALSE, 10);
7577       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7578       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7579       gtk_widget_show (box2);
7580
7581
7582       adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
7583
7584       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7585       gtk_widget_set_usize (GTK_WIDGET (scale), 150, -1);
7586       gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
7587       gtk_scale_set_digits (GTK_SCALE (scale), 1);
7588       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7589       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7590       gtk_widget_show (scale);
7591
7592       scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
7593       gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
7594                                    GTK_UPDATE_CONTINUOUS);
7595       gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
7596       gtk_widget_show (scrollbar);
7597
7598       scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
7599       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7600       gtk_signal_connect (GTK_OBJECT (scale),
7601                           "format_value",
7602                           GTK_SIGNAL_FUNC (reformat_value),
7603                           NULL);
7604       gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
7605       gtk_widget_show (scale);
7606       
7607       hbox = gtk_hbox_new (FALSE, 0);
7608
7609       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7610       gtk_widget_set_usize (scale, -1, 200);
7611       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7612       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7613       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7614       gtk_widget_show (scale);
7615
7616       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7617       gtk_widget_set_usize (scale, -1, 200);
7618       gtk_scale_set_digits (GTK_SCALE (scale), 2);
7619       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7620       gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
7621       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7622       gtk_widget_show (scale);
7623
7624       scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment));
7625       gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
7626       gtk_signal_connect (GTK_OBJECT (scale),
7627                           "format_value",
7628                           GTK_SIGNAL_FUNC (reformat_value),
7629                           NULL);
7630       gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
7631       gtk_widget_show (scale);
7632
7633       
7634       gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
7635       gtk_widget_show (hbox);
7636       
7637       separator = gtk_hseparator_new ();
7638       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7639       gtk_widget_show (separator);
7640
7641
7642       box2 = gtk_vbox_new (FALSE, 10);
7643       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7644       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7645       gtk_widget_show (box2);
7646
7647
7648       button = gtk_button_new_with_label ("close");
7649       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7650                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7651                                  GTK_OBJECT (window));
7652       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7653       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7654       gtk_widget_grab_default (button);
7655       gtk_widget_show (button);
7656     }
7657
7658   if (!GTK_WIDGET_VISIBLE (window))
7659     gtk_widget_show (window);
7660   else
7661     gtk_widget_destroy (window);
7662 }
7663
7664 /*
7665  * GtkRulers
7666  */
7667
7668 void
7669 create_rulers (GtkWidget *widget)
7670 {
7671   static GtkWidget *window = NULL;
7672   GtkWidget *table;
7673   GtkWidget *ruler;
7674
7675   if (!window)
7676     {
7677       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7678
7679       gtk_window_set_screen (GTK_WINDOW (window),
7680                              gtk_widget_get_screen (widget));
7681
7682       gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE);
7683
7684       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7685                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7686                           &window);
7687
7688       gtk_window_set_title (GTK_WINDOW (window), "rulers");
7689       gtk_widget_set_usize (window, 300, 300);
7690       gtk_widget_set_events (window, 
7691                              GDK_POINTER_MOTION_MASK 
7692                              | GDK_POINTER_MOTION_HINT_MASK);
7693       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7694
7695       table = gtk_table_new (2, 2, FALSE);
7696       gtk_container_add (GTK_CONTAINER (window), table);
7697       gtk_widget_show (table);
7698
7699       ruler = gtk_hruler_new ();
7700       gtk_ruler_set_metric (GTK_RULER (ruler), GTK_CENTIMETERS);
7701       gtk_ruler_set_range (GTK_RULER (ruler), 100, 0, 0, 20);
7702
7703       gtk_signal_connect_object (GTK_OBJECT (window), 
7704                                  "motion_notify_event",
7705                                  GTK_SIGNAL_FUNC (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7706                                  GTK_OBJECT (ruler));
7707       
7708       gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
7709                         GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
7710       gtk_widget_show (ruler);
7711
7712
7713       ruler = gtk_vruler_new ();
7714       gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
7715
7716       gtk_signal_connect_object (GTK_OBJECT (window), 
7717                                  "motion_notify_event",
7718                                  GTK_SIGNAL_FUNC (GTK_WIDGET_GET_CLASS (ruler)->motion_notify_event),
7719                                  GTK_OBJECT (ruler));
7720       
7721       gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
7722                         GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
7723       gtk_widget_show (ruler);
7724     }
7725
7726   if (!GTK_WIDGET_VISIBLE (window))
7727     gtk_widget_show (window);
7728   else
7729     gtk_widget_destroy (window);
7730 }
7731
7732 static void
7733 text_toggle_editable (GtkWidget *checkbutton,
7734                        GtkWidget *text)
7735 {
7736    gtk_text_set_editable(GTK_TEXT(text),
7737                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7738 }
7739
7740 static void
7741 text_toggle_word_wrap (GtkWidget *checkbutton,
7742                        GtkWidget *text)
7743 {
7744    gtk_text_set_word_wrap(GTK_TEXT(text),
7745                           GTK_TOGGLE_BUTTON(checkbutton)->active);
7746 }
7747
7748 struct {
7749   GdkColor color;
7750   gchar *name;
7751 } text_colors[] = {
7752  { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
7753  { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
7754  { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
7755  { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
7756  { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" }, 
7757  { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
7758  { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
7759  { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
7760 };
7761
7762 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
7763
7764 /*
7765  * GtkText
7766  */
7767 void
7768 text_insert_random (GtkWidget *w, GtkText *text)
7769 {
7770   int i;
7771   char c;
7772    for (i=0; i<10; i++)
7773     {
7774       c = 'A' + rand() % ('Z' - 'A');
7775       gtk_text_set_point (text, rand() % gtk_text_get_length (text));
7776       gtk_text_insert (text, NULL, NULL, NULL, &c, 1);
7777     }
7778 }
7779
7780 void
7781 create_text (GtkWidget *widget)
7782 {
7783   int i, j;
7784
7785   static GtkWidget *window = NULL;
7786   GtkWidget *box1;
7787   GtkWidget *box2;
7788   GtkWidget *hbox;
7789   GtkWidget *button;
7790   GtkWidget *check;
7791   GtkWidget *separator;
7792   GtkWidget *scrolled_window;
7793   GtkWidget *text;
7794
7795   FILE *infile;
7796
7797   if (!window)
7798     {
7799       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7800       gtk_window_set_screen (GTK_WINDOW (window),
7801                              gtk_widget_get_screen (widget));
7802
7803       gtk_widget_set_name (window, "text window");
7804       gtk_widget_set_usize (window, 500, 500);
7805       gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
7806
7807       gtk_signal_connect (GTK_OBJECT (window), "destroy",
7808                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
7809                           &window);
7810
7811       gtk_window_set_title (GTK_WINDOW (window), "test");
7812       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7813
7814
7815       box1 = gtk_vbox_new (FALSE, 0);
7816       gtk_container_add (GTK_CONTAINER (window), box1);
7817       gtk_widget_show (box1);
7818
7819
7820       box2 = gtk_vbox_new (FALSE, 10);
7821       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7822       gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
7823       gtk_widget_show (box2);
7824
7825
7826       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
7827       gtk_box_pack_start (GTK_BOX (box2), scrolled_window, TRUE, TRUE, 0);
7828       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
7829                                       GTK_POLICY_NEVER,
7830                                       GTK_POLICY_ALWAYS);
7831       gtk_widget_show (scrolled_window);
7832
7833       text = gtk_text_new (NULL, NULL);
7834       gtk_text_set_editable (GTK_TEXT (text), TRUE);
7835       gtk_container_add (GTK_CONTAINER (scrolled_window), text);
7836       gtk_widget_grab_focus (text);
7837       gtk_widget_show (text);
7838
7839
7840       gtk_text_freeze (GTK_TEXT (text));
7841
7842       for (i=0; i<ntext_colors; i++)
7843         {
7844           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, 
7845                            text_colors[i].name, -1);
7846           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\t", -1);
7847
7848           for (j=0; j<ntext_colors; j++)
7849             {
7850               gtk_text_insert (GTK_TEXT (text), NULL,
7851                                &text_colors[j].color, &text_colors[i].color,
7852                                "XYZ", -1);
7853             }
7854           gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "\n", -1);
7855         }
7856
7857       infile = fopen("testgtk.c", "r");
7858       
7859       if (infile)
7860         {
7861           char *buffer;
7862           int nbytes_read, nbytes_alloc;
7863           
7864           nbytes_read = 0;
7865           nbytes_alloc = 1024;
7866           buffer = g_new (char, nbytes_alloc);
7867           while (1)
7868             {
7869               int len;
7870               if (nbytes_alloc < nbytes_read + 1024)
7871                 {
7872                   nbytes_alloc *= 2;
7873                   buffer = g_realloc (buffer, nbytes_alloc);
7874                 }
7875               len = fread (buffer + nbytes_read, 1, 1024, infile);
7876               nbytes_read += len;
7877               if (len < 1024)
7878                 break;
7879             }
7880           
7881           gtk_text_insert (GTK_TEXT (text), NULL, NULL,
7882                            NULL, buffer, nbytes_read);
7883           g_free(buffer);
7884           fclose (infile);
7885         }
7886       
7887       gtk_text_thaw (GTK_TEXT (text));
7888
7889       hbox = gtk_hbutton_box_new ();
7890       gtk_box_pack_start (GTK_BOX (box2), hbox, FALSE, FALSE, 0);
7891       gtk_widget_show (hbox);
7892
7893       check = gtk_check_button_new_with_label("Editable");
7894       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
7895       gtk_signal_connect (GTK_OBJECT(check), "toggled",
7896                           GTK_SIGNAL_FUNC(text_toggle_editable), text);
7897       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
7898       gtk_widget_show (check);
7899
7900       check = gtk_check_button_new_with_label("Wrap Words");
7901       gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, TRUE, 0);
7902       gtk_signal_connect (GTK_OBJECT(check), "toggled",
7903                           GTK_SIGNAL_FUNC(text_toggle_word_wrap), text);
7904       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
7905       gtk_widget_show (check);
7906
7907       separator = gtk_hseparator_new ();
7908       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7909       gtk_widget_show (separator);
7910
7911
7912       box2 = gtk_vbox_new (FALSE, 10);
7913       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7914       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7915       gtk_widget_show (box2);
7916
7917
7918       button = gtk_button_new_with_label ("insert random");
7919       gtk_signal_connect (GTK_OBJECT (button), "clicked",
7920                           GTK_SIGNAL_FUNC(text_insert_random),
7921                           GTK_TEXT (text));
7922       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7923       gtk_widget_show (button);
7924
7925       button = gtk_button_new_with_label ("close");
7926       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
7927                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
7928                                  GTK_OBJECT (window));
7929       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7930       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
7931       gtk_widget_grab_default (button);
7932       gtk_widget_show (button);
7933     }
7934
7935   if (!GTK_WIDGET_VISIBLE (window))
7936     gtk_widget_show (window);
7937   else
7938     gtk_widget_destroy (window);
7939 }
7940
7941 /*
7942  * GtkNotebook
7943  */
7944
7945 GdkPixbuf *book_open;
7946 GdkPixbuf *book_closed;
7947 GtkWidget *sample_notebook;
7948
7949 static void
7950 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
7951 {
7952   GtkWidget *page_widget;
7953   GtkWidget *pixwid;
7954
7955   page_widget = gtk_notebook_get_nth_page (notebook, page_num);
7956
7957   pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "tab_pixmap");
7958   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
7959   
7960   pixwid = gtk_object_get_data (GTK_OBJECT (page_widget), "menu_pixmap");
7961   gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
7962 }
7963
7964 static void
7965 page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num)
7966 {
7967   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
7968   gint old_page_num = gtk_notebook_get_current_page (notebook);
7969  
7970   if (page_num == old_page_num)
7971     return;
7972
7973   set_page_image (notebook, page_num, book_open);
7974
7975   if (old_page_num != -1)
7976     set_page_image (notebook, old_page_num, book_closed);
7977 }
7978
7979 static void
7980 tab_fill (GtkToggleButton *button, GtkWidget *child)
7981 {
7982   gboolean expand;
7983   GtkPackType pack_type;
7984
7985   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7986                                         &expand, NULL, &pack_type);
7987   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7988                                       expand, button->active, pack_type);
7989 }
7990
7991 static void
7992 tab_expand (GtkToggleButton *button, GtkWidget *child)
7993 {
7994   gboolean fill;
7995   GtkPackType pack_type;
7996
7997   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
7998                                         NULL, &fill, &pack_type);
7999   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8000                                       button->active, fill, pack_type);
8001 }
8002
8003 static void
8004 tab_pack (GtkToggleButton *button, GtkWidget *child)
8005           
8006
8007   gboolean expand;
8008   gboolean fill;
8009
8010   gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8011                                         &expand, &fill, NULL);
8012   gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child,
8013                                       expand, fill, button->active);
8014 }
8015
8016 static void
8017 create_pages (GtkNotebook *notebook, gint start, gint end)
8018 {
8019   GtkWidget *child = NULL;
8020   GtkWidget *button;
8021   GtkWidget *label;
8022   GtkWidget *hbox;
8023   GtkWidget *vbox;
8024   GtkWidget *label_box;
8025   GtkWidget *menu_box;
8026   GtkWidget *pixwid;
8027   gint i;
8028   char buffer[32];
8029   char accel_buffer[32];
8030
8031   for (i = start; i <= end; i++)
8032     {
8033       sprintf (buffer, "Page %d", i);
8034       sprintf (accel_buffer, "Page _%d", i);
8035
8036       child = gtk_frame_new (buffer);
8037       gtk_container_set_border_width (GTK_CONTAINER (child), 10);
8038
8039       vbox = gtk_vbox_new (TRUE,0);
8040       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8041       gtk_container_add (GTK_CONTAINER (child), vbox);
8042
8043       hbox = gtk_hbox_new (TRUE,0);
8044       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
8045
8046       button = gtk_check_button_new_with_label ("Fill Tab");
8047       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8048       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
8049       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8050                           GTK_SIGNAL_FUNC (tab_fill), child);
8051
8052       button = gtk_check_button_new_with_label ("Expand Tab");
8053       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8054       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8055       GTK_SIGNAL_FUNC (tab_expand), child);
8056
8057       button = gtk_check_button_new_with_label ("Pack end");
8058       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
8059       gtk_signal_connect (GTK_OBJECT (button), "toggled",
8060                           GTK_SIGNAL_FUNC (tab_pack), child);
8061
8062       button = gtk_button_new_with_label ("Hide Page");
8063       gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
8064       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8065                                  GTK_SIGNAL_FUNC (gtk_widget_hide),
8066                                  GTK_OBJECT (child));
8067
8068       gtk_widget_show_all (child);
8069
8070       label_box = gtk_hbox_new (FALSE, 0);
8071       pixwid = gtk_image_new_from_pixbuf (book_closed);
8072       gtk_object_set_data (GTK_OBJECT (child), "tab_pixmap", pixwid);
8073                            
8074       gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
8075       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8076       label = gtk_label_new_with_mnemonic (accel_buffer);
8077       gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
8078       gtk_widget_show_all (label_box);
8079       
8080                                        
8081       menu_box = gtk_hbox_new (FALSE, 0);
8082       pixwid = gtk_image_new_from_pixbuf (book_closed);
8083       gtk_object_set_data (GTK_OBJECT (child), "menu_pixmap", pixwid);
8084       
8085       gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
8086       gtk_misc_set_padding (GTK_MISC (pixwid), 3, 1);
8087       label = gtk_label_new (buffer);
8088       gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
8089       gtk_widget_show_all (menu_box);
8090
8091       gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
8092     }
8093 }
8094
8095 static void
8096 rotate_notebook (GtkButton   *button,
8097                  GtkNotebook *notebook)
8098 {
8099   gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
8100 }
8101
8102 static void
8103 show_all_pages (GtkButton   *button,
8104                 GtkNotebook *notebook)
8105 {  
8106   gtk_container_foreach (GTK_CONTAINER (notebook),
8107                          (GtkCallback) gtk_widget_show, NULL);
8108 }
8109
8110 static void
8111 notebook_type_changed (GtkWidget *optionmenu,
8112                        gpointer   data)
8113 {
8114   GtkNotebook *notebook;
8115   gint i, c;
8116
8117   enum {
8118     STANDARD,
8119     NOTABS,
8120     BORDERLESS,
8121     SCROLLABLE
8122   };
8123
8124   notebook = GTK_NOTEBOOK (data);
8125
8126   c = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
8127
8128   switch (c)
8129     {
8130     case STANDARD:
8131       /* standard notebook */
8132       gtk_notebook_set_show_tabs (notebook, TRUE);
8133       gtk_notebook_set_show_border (notebook, TRUE);
8134       gtk_notebook_set_scrollable (notebook, FALSE);
8135       break;
8136
8137     case NOTABS:
8138       /* notabs notebook */
8139       gtk_notebook_set_show_tabs (notebook, FALSE);
8140       gtk_notebook_set_show_border (notebook, TRUE);
8141       break;
8142
8143     case BORDERLESS:
8144       /* borderless */
8145       gtk_notebook_set_show_tabs (notebook, FALSE);
8146       gtk_notebook_set_show_border (notebook, FALSE);
8147       break;
8148
8149     case SCROLLABLE:  
8150       /* scrollable */
8151       gtk_notebook_set_show_tabs (notebook, TRUE);
8152       gtk_notebook_set_show_border (notebook, TRUE);
8153       gtk_notebook_set_scrollable (notebook, TRUE);
8154       if (g_list_length (notebook->children) == 5)
8155         create_pages (notebook, 6, 15);
8156       
8157       return;
8158       break;
8159     }
8160   
8161   if (g_list_length (notebook->children) == 15)
8162     for (i = 0; i < 10; i++)
8163       gtk_notebook_remove_page (notebook, 5);
8164 }
8165
8166 static void
8167 notebook_popup (GtkToggleButton *button,
8168                 GtkNotebook     *notebook)
8169 {
8170   if (button->active)
8171     gtk_notebook_popup_enable (notebook);
8172   else
8173     gtk_notebook_popup_disable (notebook);
8174 }
8175
8176 static void
8177 notebook_homogeneous (GtkToggleButton *button,
8178                       GtkNotebook     *notebook)
8179 {
8180   gtk_notebook_set_homogeneous_tabs (notebook, button->active);
8181 }
8182
8183 static void
8184 create_notebook (GtkWidget *widget)
8185 {
8186   static GtkWidget *window = NULL;
8187   GtkWidget *box1;
8188   GtkWidget *box2;
8189   GtkWidget *button;
8190   GtkWidget *separator;
8191   GtkWidget *omenu;
8192   GtkWidget *label;
8193
8194   static gchar *items[] =
8195   {
8196     "Standard",
8197     "No tabs",
8198     "Borderless",
8199     "Scrollable"
8200   };
8201   
8202   if (!window)
8203     {
8204       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8205       gtk_window_set_screen (GTK_WINDOW (window),
8206                              gtk_widget_get_screen (widget));
8207
8208       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8209                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8210                           &window);
8211
8212       gtk_window_set_title (GTK_WINDOW (window), "notebook");
8213       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8214
8215       box1 = gtk_vbox_new (FALSE, 0);
8216       gtk_container_add (GTK_CONTAINER (window), box1);
8217
8218       sample_notebook = gtk_notebook_new ();
8219       gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page",
8220                           GTK_SIGNAL_FUNC (page_switch), NULL);
8221       gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
8222       gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
8223       gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
8224
8225       gtk_widget_realize (sample_notebook);
8226
8227       if (!book_open)
8228         book_open = gdk_pixbuf_new_from_xpm_data ((const char **)book_open_xpm);
8229                                                   
8230       if (!book_closed)
8231         book_closed = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
8232
8233       create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
8234
8235       separator = gtk_hseparator_new ();
8236       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
8237       
8238       box2 = gtk_hbox_new (FALSE, 5);
8239       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8240       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8241
8242       button = gtk_check_button_new_with_label ("popup menu");
8243       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8244       gtk_signal_connect (GTK_OBJECT(button), "clicked",
8245                           GTK_SIGNAL_FUNC (notebook_popup),
8246                           GTK_OBJECT (sample_notebook));
8247
8248       button = gtk_check_button_new_with_label ("homogeneous tabs");
8249       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
8250       gtk_signal_connect (GTK_OBJECT(button), "clicked",
8251                           GTK_SIGNAL_FUNC (notebook_homogeneous),
8252                           GTK_OBJECT (sample_notebook));
8253
8254       box2 = gtk_hbox_new (FALSE, 5);
8255       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8256       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8257
8258       label = gtk_label_new ("Notebook Style :");
8259       gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
8260
8261       omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
8262                                  notebook_type_changed,
8263                                  sample_notebook);
8264       gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
8265
8266       button = gtk_button_new_with_label ("Show all Pages");
8267       gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
8268       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8269                           GTK_SIGNAL_FUNC (show_all_pages), sample_notebook);
8270
8271       box2 = gtk_hbox_new (TRUE, 10);
8272       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
8273       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
8274
8275       button = gtk_button_new_with_label ("prev");
8276       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8277                                  GTK_SIGNAL_FUNC (gtk_notebook_prev_page),
8278                                  GTK_OBJECT (sample_notebook));
8279       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8280
8281       button = gtk_button_new_with_label ("next");
8282       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8283                                  GTK_SIGNAL_FUNC (gtk_notebook_next_page),
8284                                  GTK_OBJECT (sample_notebook));
8285       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8286
8287       button = gtk_button_new_with_label ("rotate");
8288       gtk_signal_connect (GTK_OBJECT (button), "clicked",
8289                           GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook);
8290       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
8291
8292       separator = gtk_hseparator_new ();
8293       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
8294
8295       button = gtk_button_new_with_label ("close");
8296       gtk_container_set_border_width (GTK_CONTAINER (button), 5);
8297       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
8298                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
8299                                  GTK_OBJECT (window));
8300       gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
8301       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8302       gtk_widget_grab_default (button);
8303     }
8304
8305   if (!GTK_WIDGET_VISIBLE (window))
8306     gtk_widget_show_all (window);
8307   else
8308     gtk_widget_destroy (window);
8309 }
8310
8311 /*
8312  * GtkPanes
8313  */
8314
8315 void
8316 toggle_resize (GtkWidget *widget, GtkWidget *child)
8317 {
8318   GtkPaned *paned = GTK_PANED (child->parent);
8319   gboolean is_child1 = (child == paned->child1);
8320   gboolean resize, shrink;
8321
8322   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8323   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8324
8325   gtk_widget_ref (child);
8326   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8327   if (is_child1)
8328     gtk_paned_pack1 (paned, child, !resize, shrink);
8329   else
8330     gtk_paned_pack2 (paned, child, !resize, shrink);
8331   gtk_widget_unref (child);
8332 }
8333
8334 void
8335 toggle_shrink (GtkWidget *widget, GtkWidget *child)
8336 {
8337   GtkPaned *paned = GTK_PANED (child->parent);
8338   gboolean is_child1 = (child == paned->child1);
8339   gboolean resize, shrink;
8340
8341   resize = is_child1 ? paned->child1_resize : paned->child2_resize;
8342   shrink = is_child1 ? paned->child1_shrink : paned->child2_shrink;
8343
8344   gtk_widget_ref (child);
8345   gtk_container_remove (GTK_CONTAINER (child->parent), child);
8346   if (is_child1)
8347     gtk_paned_pack1 (paned, child, resize, !shrink);
8348   else
8349     gtk_paned_pack2 (paned, child, resize, !shrink);
8350   gtk_widget_unref (child);
8351 }
8352
8353 static void
8354 paned_props_clicked (GtkWidget *button,
8355                      GObject   *paned)
8356 {
8357   GtkWidget *window = create_prop_editor (paned, GTK_TYPE_PANED);
8358   
8359   gtk_window_set_title (GTK_WINDOW (window), "Paned Properties");
8360 }
8361
8362 GtkWidget *
8363 create_pane_options (GtkPaned    *paned,
8364                      const gchar *frame_label,
8365                      const gchar *label1,
8366                      const gchar *label2)
8367 {
8368   GtkWidget *frame;
8369   GtkWidget *table;
8370   GtkWidget *label;
8371   GtkWidget *button;
8372   GtkWidget *check_button;
8373   
8374   frame = gtk_frame_new (frame_label);
8375   gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
8376   
8377   table = gtk_table_new (4, 2, 4);
8378   gtk_container_add (GTK_CONTAINER (frame), table);
8379   
8380   label = gtk_label_new (label1);
8381   gtk_table_attach_defaults (GTK_TABLE (table), label,
8382                              0, 1, 0, 1);
8383   
8384   check_button = gtk_check_button_new_with_label ("Resize");
8385   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8386                              0, 1, 1, 2);
8387   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8388                       GTK_SIGNAL_FUNC (toggle_resize),
8389                       paned->child1);
8390   
8391   check_button = gtk_check_button_new_with_label ("Shrink");
8392   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8393                              0, 1, 2, 3);
8394   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8395                                TRUE);
8396   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8397                       GTK_SIGNAL_FUNC (toggle_shrink),
8398                       paned->child1);
8399   
8400   label = gtk_label_new (label2);
8401   gtk_table_attach_defaults (GTK_TABLE (table), label,
8402                              1, 2, 0, 1);
8403   
8404   check_button = gtk_check_button_new_with_label ("Resize");
8405   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8406                              1, 2, 1, 2);
8407   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8408                                TRUE);
8409   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8410                       GTK_SIGNAL_FUNC (toggle_resize),
8411                       paned->child2);
8412   
8413   check_button = gtk_check_button_new_with_label ("Shrink");
8414   gtk_table_attach_defaults (GTK_TABLE (table), check_button,
8415                              1, 2, 2, 3);
8416   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
8417                                TRUE);
8418   gtk_signal_connect (GTK_OBJECT (check_button), "toggled",
8419                       GTK_SIGNAL_FUNC (toggle_shrink),
8420                       paned->child2);
8421
8422   button = gtk_button_new_with_mnemonic ("_Properties");
8423   gtk_table_attach_defaults (GTK_TABLE (table), button,
8424                              0, 2, 3, 4);
8425   gtk_signal_connect (GTK_OBJECT (button), "clicked",
8426                       GTK_SIGNAL_FUNC (paned_props_clicked),
8427                       paned);
8428
8429   return frame;
8430 }
8431
8432 void
8433 create_panes (GtkWidget *widget)
8434 {
8435   static GtkWidget *window = NULL;
8436   GtkWidget *frame;
8437   GtkWidget *hpaned;
8438   GtkWidget *vpaned;
8439   GtkWidget *button;
8440   GtkWidget *vbox;
8441
8442   if (!window)
8443     {
8444       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8445
8446       gtk_window_set_screen (GTK_WINDOW (window),
8447                              gtk_widget_get_screen (widget));
8448       
8449       gtk_signal_connect (GTK_OBJECT (window), "destroy",
8450                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8451                           &window);
8452
8453       gtk_window_set_title (GTK_WINDOW (window), "Panes");
8454       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8455
8456       vbox = gtk_vbox_new (FALSE, 0);
8457       gtk_container_add (GTK_CONTAINER (window), vbox);
8458       
8459       vpaned = gtk_vpaned_new ();
8460       gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
8461       gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
8462
8463       hpaned = gtk_hpaned_new ();
8464       gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
8465
8466       frame = gtk_frame_new (NULL);
8467       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8468       gtk_widget_set_usize (frame, 60, 60);
8469       gtk_paned_add1 (GTK_PANED (hpaned), frame);
8470       
8471       button = gtk_button_new_with_label ("Hi there");
8472       gtk_container_add (GTK_CONTAINER(frame), button);
8473
8474       frame = gtk_frame_new (NULL);
8475       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8476       gtk_widget_set_usize (frame, 80, 60);
8477       gtk_paned_add2 (GTK_PANED (hpaned), frame);
8478
8479       frame = gtk_frame_new (NULL);
8480       gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
8481       gtk_widget_set_usize (frame, 60, 80);
8482       gtk_paned_add2 (GTK_PANED (vpaned), frame);
8483
8484       /* Now create toggle buttons to control sizing */
8485
8486       gtk_box_pack_start (GTK_BOX (vbox),
8487                           create_pane_options (GTK_PANED (hpaned),
8488                                                "Horizontal",
8489                                                "Left",
8490                                                "Right"),
8491                           FALSE, FALSE, 0);
8492
8493       gtk_box_pack_start (GTK_BOX (vbox),
8494                           create_pane_options (GTK_PANED (vpaned),
8495                                                "Vertical",
8496                                                "Top",
8497                                                "Bottom"),
8498                           FALSE, FALSE, 0);
8499
8500       gtk_widget_show_all (vbox);
8501     }
8502
8503   if (!GTK_WIDGET_VISIBLE (window))
8504     gtk_widget_show (window);
8505   else
8506     gtk_widget_destroy (window);
8507 }
8508
8509 /*
8510  * Paned keyboard navigation
8511  */
8512
8513 static GtkWidget*
8514 paned_keyboard_window1 (GtkWidget *widget)
8515 {
8516   GtkWidget *window1;
8517   GtkWidget *hpaned1;
8518   GtkWidget *frame1;
8519   GtkWidget *vbox1;
8520   GtkWidget *button7;
8521   GtkWidget *button8;
8522   GtkWidget *button9;
8523   GtkWidget *vpaned1;
8524   GtkWidget *frame2;
8525   GtkWidget *frame5;
8526   GtkWidget *hbox1;
8527   GtkWidget *button5;
8528   GtkWidget *button6;
8529   GtkWidget *frame3;
8530   GtkWidget *frame4;
8531   GtkWidget *table1;
8532   GtkWidget *button1;
8533   GtkWidget *button2;
8534   GtkWidget *button3;
8535   GtkWidget *button4;
8536
8537   window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8538   gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
8539   gtk_window_set_screen (GTK_WINDOW (window1), 
8540                          gtk_widget_get_screen (widget));
8541
8542   hpaned1 = gtk_hpaned_new ();
8543   gtk_container_add (GTK_CONTAINER (window1), hpaned1);
8544
8545   frame1 = gtk_frame_new (NULL);
8546   gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
8547   gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
8548
8549   vbox1 = gtk_vbox_new (FALSE, 0);
8550   gtk_container_add (GTK_CONTAINER (frame1), vbox1);
8551
8552   button7 = gtk_button_new_with_label ("button7");
8553   gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
8554
8555   button8 = gtk_button_new_with_label ("button8");
8556   gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
8557
8558   button9 = gtk_button_new_with_label ("button9");
8559   gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
8560
8561   vpaned1 = gtk_vpaned_new ();
8562   gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
8563
8564   frame2 = gtk_frame_new (NULL);
8565   gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
8566   gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
8567
8568   frame5 = gtk_frame_new (NULL);
8569   gtk_container_add (GTK_CONTAINER (frame2), frame5);
8570
8571   hbox1 = gtk_hbox_new (FALSE, 0);
8572   gtk_container_add (GTK_CONTAINER (frame5), hbox1);
8573
8574   button5 = gtk_button_new_with_label ("button5");
8575   gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
8576
8577   button6 = gtk_button_new_with_label ("button6");
8578   gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
8579
8580   frame3 = gtk_frame_new (NULL);
8581   gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
8582   gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
8583
8584   frame4 = gtk_frame_new ("Buttons");
8585   gtk_container_add (GTK_CONTAINER (frame3), frame4);
8586   gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
8587
8588   table1 = gtk_table_new (2, 2, FALSE);
8589   gtk_container_add (GTK_CONTAINER (frame4), table1);
8590   gtk_container_set_border_width (GTK_CONTAINER (table1), 11);
8591
8592   button1 = gtk_button_new_with_label ("button1");
8593   gtk_table_attach (GTK_TABLE (table1), button1, 0, 1, 0, 1,
8594                     (GtkAttachOptions) (GTK_FILL),
8595                     (GtkAttachOptions) (0), 0, 0);
8596
8597   button2 = gtk_button_new_with_label ("button2");
8598   gtk_table_attach (GTK_TABLE (table1), button2, 1, 2, 0, 1,
8599                     (GtkAttachOptions) (GTK_FILL),
8600                     (GtkAttachOptions) (0), 0, 0);
8601
8602   button3 = gtk_button_new_with_label ("button3");
8603   gtk_table_attach (GTK_TABLE (table1), button3, 0, 1, 1, 2,
8604                     (GtkAttachOptions) (GTK_FILL),
8605                     (GtkAttachOptions) (0), 0, 0);
8606
8607   button4 = gtk_button_new_with_label ("button4");
8608   gtk_table_attach (GTK_TABLE (table1), button4, 1, 2, 1, 2,
8609                     (GtkAttachOptions) (GTK_FILL),
8610                     (GtkAttachOptions) (0), 0, 0);
8611
8612   return window1;
8613 }
8614
8615 static GtkWidget*
8616 paned_keyboard_window2 (GtkWidget *widget)
8617 {
8618   GtkWidget *window2;
8619   GtkWidget *hpaned2;
8620   GtkWidget *frame6;
8621   GtkWidget *button13;
8622   GtkWidget *hbox2;
8623   GtkWidget *vpaned2;
8624   GtkWidget *frame7;
8625   GtkWidget *button12;
8626   GtkWidget *frame8;
8627   GtkWidget *button11;
8628   GtkWidget *button10;
8629
8630   window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8631   gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
8632
8633   gtk_window_set_screen (GTK_WINDOW (window2), 
8634                          gtk_widget_get_screen (widget));
8635
8636   hpaned2 = gtk_hpaned_new ();
8637   gtk_container_add (GTK_CONTAINER (window2), hpaned2);
8638
8639   frame6 = gtk_frame_new (NULL);
8640   gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
8641   gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
8642
8643   button13 = gtk_button_new_with_label ("button13");
8644   gtk_container_add (GTK_CONTAINER (frame6), button13);
8645
8646   hbox2 = gtk_hbox_new (FALSE, 0);
8647   gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
8648
8649   vpaned2 = gtk_vpaned_new ();
8650   gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
8651
8652   frame7 = gtk_frame_new (NULL);
8653   gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
8654   gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
8655
8656   button12 = gtk_button_new_with_label ("button12");
8657   gtk_container_add (GTK_CONTAINER (frame7), button12);
8658
8659   frame8 = gtk_frame_new (NULL);
8660   gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
8661   gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
8662
8663   button11 = gtk_button_new_with_label ("button11");
8664   gtk_container_add (GTK_CONTAINER (frame8), button11);
8665
8666   button10 = gtk_button_new_with_label ("button10");
8667   gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
8668
8669   return window2;
8670 }
8671
8672 static GtkWidget*
8673 paned_keyboard_window3 (GtkWidget *widget)
8674 {
8675   GtkWidget *window3;
8676   GtkWidget *vbox2;
8677   GtkWidget *label1;
8678   GtkWidget *hpaned3;
8679   GtkWidget *frame9;
8680   GtkWidget *button14;
8681   GtkWidget *hpaned4;
8682   GtkWidget *frame10;
8683   GtkWidget *button15;
8684   GtkWidget *hpaned5;
8685   GtkWidget *frame11;
8686   GtkWidget *button16;
8687   GtkWidget *frame12;
8688   GtkWidget *button17;
8689
8690   window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8691   gtk_object_set_data (GTK_OBJECT (window3), "window3", window3);
8692   gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
8693
8694   gtk_window_set_screen (GTK_WINDOW (window3), 
8695                          gtk_widget_get_screen (widget));
8696   
8697
8698   vbox2 = gtk_vbox_new (FALSE, 0);
8699   gtk_container_add (GTK_CONTAINER (window3), vbox2);
8700
8701   label1 = gtk_label_new ("Three panes nested inside each other");
8702   gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
8703
8704   hpaned3 = gtk_hpaned_new ();
8705   gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
8706
8707   frame9 = gtk_frame_new (NULL);
8708   gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
8709   gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
8710
8711   button14 = gtk_button_new_with_label ("button14");
8712   gtk_container_add (GTK_CONTAINER (frame9), button14);
8713
8714   hpaned4 = gtk_hpaned_new ();
8715   gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
8716
8717   frame10 = gtk_frame_new (NULL);
8718   gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
8719   gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
8720
8721   button15 = gtk_button_new_with_label ("button15");
8722   gtk_container_add (GTK_CONTAINER (frame10), button15);
8723
8724   hpaned5 = gtk_hpaned_new ();
8725   gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
8726
8727   frame11 = gtk_frame_new (NULL);
8728   gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
8729   gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
8730
8731   button16 = gtk_button_new_with_label ("button16");
8732   gtk_container_add (GTK_CONTAINER (frame11), button16);
8733
8734   frame12 = gtk_frame_new (NULL);
8735   gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
8736   gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
8737
8738   button17 = gtk_button_new_with_label ("button17");
8739   gtk_container_add (GTK_CONTAINER (frame12), button17);
8740
8741   return window3;
8742 }
8743
8744 static GtkWidget*
8745 paned_keyboard_window4 (GtkWidget *widget)
8746 {
8747   GtkWidget *window4;
8748   GtkWidget *vbox3;
8749   GtkWidget *label2;
8750   GtkWidget *hpaned6;
8751   GtkWidget *vpaned3;
8752   GtkWidget *button19;
8753   GtkWidget *button18;
8754   GtkWidget *hbox3;
8755   GtkWidget *vpaned4;
8756   GtkWidget *button21;
8757   GtkWidget *button20;
8758   GtkWidget *vpaned5;
8759   GtkWidget *button23;
8760   GtkWidget *button22;
8761   GtkWidget *vpaned6;
8762   GtkWidget *button25;
8763   GtkWidget *button24;
8764
8765   window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8766   gtk_object_set_data (GTK_OBJECT (window4), "window4", window4);
8767   gtk_window_set_title (GTK_WINDOW (window4), "window4");
8768
8769   gtk_window_set_screen (GTK_WINDOW (window4), 
8770                          gtk_widget_get_screen (widget));
8771
8772   vbox3 = gtk_vbox_new (FALSE, 0);
8773   gtk_container_add (GTK_CONTAINER (window4), vbox3);
8774
8775   label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n    - vpaned\n    - vpaned\n    - vpaned\n");
8776   gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
8777   gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
8778
8779   hpaned6 = gtk_hpaned_new ();
8780   gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
8781
8782   vpaned3 = gtk_vpaned_new ();
8783   gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
8784
8785   button19 = gtk_button_new_with_label ("button19");
8786   gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
8787
8788   button18 = gtk_button_new_with_label ("button18");
8789   gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
8790
8791   hbox3 = gtk_hbox_new (FALSE, 0);
8792   gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
8793
8794   vpaned4 = gtk_vpaned_new ();
8795   gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
8796
8797   button21 = gtk_button_new_with_label ("button21");
8798   gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
8799
8800   button20 = gtk_button_new_with_label ("button20");
8801   gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
8802
8803   vpaned5 = gtk_vpaned_new ();
8804   gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
8805
8806   button23 = gtk_button_new_with_label ("button23");
8807   gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
8808
8809   button22 = gtk_button_new_with_label ("button22");
8810   gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
8811
8812   vpaned6 = gtk_vpaned_new ();
8813   gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
8814
8815   button25 = gtk_button_new_with_label ("button25");
8816   gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
8817
8818   button24 = gtk_button_new_with_label ("button24");
8819   gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
8820
8821   return window4;
8822 }
8823
8824 static void
8825 create_paned_keyboard_navigation (GtkWidget *widget)
8826 {
8827   static GtkWidget *window1 = NULL;
8828   static GtkWidget *window2 = NULL;
8829   static GtkWidget *window3 = NULL;
8830   static GtkWidget *window4 = NULL;
8831
8832   if (window1 && 
8833      (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
8834     {
8835       gtk_widget_destroy (window1);
8836       gtk_widget_destroy (window2);
8837       gtk_widget_destroy (window3);
8838       gtk_widget_destroy (window4);
8839     }
8840   
8841   if (!window1)
8842     {
8843       window1 = paned_keyboard_window1 (widget);
8844       gtk_signal_connect (GTK_OBJECT (window1), "destroy",
8845                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8846                           &window1);
8847     }
8848
8849   if (!window2)
8850     {
8851       window2 = paned_keyboard_window2 (widget);
8852       gtk_signal_connect (GTK_OBJECT (window2), "destroy",
8853                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8854                           &window2);
8855     }
8856
8857   if (!window3)
8858     {
8859       window3 = paned_keyboard_window3 (widget);
8860       gtk_signal_connect (GTK_OBJECT (window3), "destroy",
8861                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8862                           &window3);
8863     }
8864
8865   if (!window4)
8866     {
8867       window4 = paned_keyboard_window4 (widget);
8868       gtk_signal_connect (GTK_OBJECT (window4), "destroy",
8869                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
8870                           &window4);
8871     }
8872
8873   if (GTK_WIDGET_VISIBLE (window1))
8874     gtk_widget_destroy (GTK_WIDGET (window1));
8875   else
8876     gtk_widget_show_all (GTK_WIDGET (window1));
8877
8878   if (GTK_WIDGET_VISIBLE (window2))
8879     gtk_widget_destroy (GTK_WIDGET (window2));
8880   else
8881     gtk_widget_show_all (GTK_WIDGET (window2));
8882
8883   if (GTK_WIDGET_VISIBLE (window3))
8884     gtk_widget_destroy (GTK_WIDGET (window3));
8885   else
8886     gtk_widget_show_all (GTK_WIDGET (window3));
8887
8888   if (GTK_WIDGET_VISIBLE (window4))
8889     gtk_widget_destroy (GTK_WIDGET (window4));
8890   else
8891     gtk_widget_show_all (GTK_WIDGET (window4));
8892 }
8893
8894
8895 /*
8896  * Shaped Windows
8897  */
8898
8899 typedef struct _cursoroffset {gint x,y;} CursorOffset;
8900
8901 static void
8902 shape_pressed (GtkWidget *widget, GdkEventButton *event)
8903 {
8904   CursorOffset *p;
8905
8906   /* ignore double and triple click */
8907   if (event->type != GDK_BUTTON_PRESS)
8908     return;
8909
8910   p = gtk_object_get_user_data (GTK_OBJECT(widget));
8911   p->x = (int) event->x;
8912   p->y = (int) event->y;
8913
8914   gtk_grab_add (widget);
8915   gdk_pointer_grab (widget->window, TRUE,
8916                     GDK_BUTTON_RELEASE_MASK |
8917                     GDK_BUTTON_MOTION_MASK |
8918                     GDK_POINTER_MOTION_HINT_MASK,
8919                     NULL, NULL, 0);
8920 }
8921
8922 static void
8923 shape_released (GtkWidget *widget)
8924 {
8925   gtk_grab_remove (widget);
8926   gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
8927                               GDK_CURRENT_TIME);
8928 }
8929
8930 static void
8931 shape_motion (GtkWidget      *widget, 
8932               GdkEventMotion *event)
8933 {
8934   gint xp, yp;
8935   CursorOffset * p;
8936   GdkModifierType mask;
8937
8938   p = gtk_object_get_user_data (GTK_OBJECT (widget));
8939
8940   /*
8941    * Can't use event->x / event->y here 
8942    * because I need absolute coordinates.
8943    */
8944   gdk_window_get_pointer (NULL, &xp, &yp, &mask);
8945   gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
8946 }
8947
8948 GtkWidget *
8949 shape_create_icon (GdkScreen *screen,
8950                    char      *xpm_file,
8951                    gint       x,
8952                    gint       y,
8953                    gint       px,
8954                    gint       py,
8955                    gint       window_type)
8956 {
8957   GtkWidget *window;
8958   GtkWidget *pixmap;
8959   GtkWidget *fixed;
8960   CursorOffset* icon_pos;
8961   GdkGC* gc;
8962   GdkBitmap *gdk_pixmap_mask;
8963   GdkPixmap *gdk_pixmap;
8964   GtkStyle *style;
8965
8966   style = gtk_widget_get_default_style ();
8967   gc = style->black_gc; 
8968
8969   /*
8970    * GDK_WINDOW_TOPLEVEL works also, giving you a title border
8971    */
8972   window = gtk_window_new (window_type);
8973   gtk_window_set_screen (GTK_WINDOW (window), screen);
8974   
8975   fixed = gtk_fixed_new ();
8976   gtk_widget_set_usize (fixed, 100,100);
8977   gtk_container_add (GTK_CONTAINER (window), fixed);
8978   gtk_widget_show (fixed);
8979   
8980   gtk_widget_set_events (window, 
8981                          gtk_widget_get_events (window) |
8982                          GDK_BUTTON_MOTION_MASK |
8983                          GDK_POINTER_MOTION_HINT_MASK |
8984                          GDK_BUTTON_PRESS_MASK);
8985
8986   gtk_widget_realize (window);
8987   gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
8988                                            &style->bg[GTK_STATE_NORMAL],
8989                                            xpm_file);
8990
8991   pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
8992   gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
8993   gtk_widget_show (pixmap);
8994   
8995   gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px, py);
8996   
8997   gdk_drawable_unref (gdk_pixmap_mask);
8998   gdk_drawable_unref (gdk_pixmap);
8999
9000   gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
9001                       GTK_SIGNAL_FUNC (shape_pressed),NULL);
9002   gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
9003                       GTK_SIGNAL_FUNC (shape_released),NULL);
9004   gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
9005                       GTK_SIGNAL_FUNC (shape_motion),NULL);
9006
9007   icon_pos = g_new (CursorOffset, 1);
9008   gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
9009
9010   gtk_widget_set_uposition (window, x, y);
9011   gtk_widget_show (window);
9012   
9013   return window;
9014 }
9015
9016 void 
9017 create_shapes (GtkWidget *widget)
9018 {
9019   /* Variables used by the Drag/Drop and Shape Window demos */
9020   static GtkWidget *modeller = NULL;
9021   static GtkWidget *sheets = NULL;
9022   static GtkWidget *rings = NULL;
9023   static GtkWidget *with_region = NULL;
9024   GdkScreen *screen = gtk_widget_get_screen (widget);
9025   
9026   if (!(file_exists ("Modeller.xpm") &&
9027         file_exists ("FilesQueue.xpm") &&
9028         file_exists ("3DRings.xpm")))
9029     return;
9030   
9031
9032   if (!modeller)
9033     {
9034       modeller = shape_create_icon (screen, "Modeller.xpm",
9035                                     440, 140, 0,0, GTK_WINDOW_POPUP);
9036
9037       gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
9038                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9039                           &modeller);
9040     }
9041   else
9042     gtk_widget_destroy (modeller);
9043
9044   if (!sheets)
9045     {
9046       sheets = shape_create_icon (screen, "FilesQueue.xpm",
9047                                   580, 170, 0,0, GTK_WINDOW_POPUP);
9048
9049       gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
9050                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9051                           &sheets);
9052
9053     }
9054   else
9055     gtk_widget_destroy (sheets);
9056
9057   if (!rings)
9058     {
9059       rings = shape_create_icon (screen, "3DRings.xpm",
9060                                  460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9061
9062       gtk_signal_connect (GTK_OBJECT (rings), "destroy",
9063                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9064                           &rings);
9065     }
9066   else
9067     gtk_widget_destroy (rings);
9068
9069   if (!with_region)
9070     {
9071       GdkRegion *region;
9072       gint x, y;
9073       
9074       with_region = shape_create_icon (screen, "3DRings.xpm",
9075                                        460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
9076
9077       gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
9078       
9079       gtk_signal_connect (GTK_OBJECT (with_region), "destroy",
9080                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9081                           &with_region);
9082
9083       /* reset shape from mask to a region */
9084       x = 0;
9085       y = 0;
9086       region = gdk_region_new ();
9087
9088       while (x < 460)
9089         {
9090           while (y < 270)
9091             {
9092               GdkRectangle rect;
9093               rect.x = x;
9094               rect.y = y;
9095               rect.width = 10;
9096               rect.height = 10;
9097
9098               gdk_region_union_with_rect (region, &rect);
9099               
9100               y += 20;
9101             }
9102           y = 0;
9103           x += 20;
9104         }
9105
9106       gdk_window_shape_combine_region (with_region->window,
9107                                        region,
9108                                        0, 0);
9109     }
9110   else
9111     gtk_widget_destroy (with_region);
9112 }
9113
9114 /*
9115  * WM Hints demo
9116  */
9117
9118 void
9119 create_wmhints (GtkWidget *widget)
9120 {
9121   static GtkWidget *window = NULL;
9122   GtkWidget *label;
9123   GtkWidget *separator;
9124   GtkWidget *button;
9125   GtkWidget *box1;
9126   GtkWidget *box2;
9127
9128   GdkBitmap *circles;
9129
9130   if (!window)
9131     {
9132       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9133
9134       gtk_window_set_screen (GTK_WINDOW (window),
9135                              gtk_widget_get_screen (widget));
9136       
9137       gtk_signal_connect (GTK_OBJECT (window), "destroy",
9138                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9139                           &window);
9140
9141       gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
9142       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9143
9144       gtk_widget_realize (window);
9145       
9146       circles = gdk_bitmap_create_from_data (window->window,
9147                                              circles_bits,
9148                                              circles_width,
9149                                              circles_height);
9150       gdk_window_set_icon (window->window, NULL,
9151                            circles, circles);
9152       
9153       gdk_window_set_icon_name (window->window, "WMHints Test Icon");
9154   
9155       gdk_window_set_decorations (window->window, GDK_DECOR_ALL | GDK_DECOR_MENU);
9156       gdk_window_set_functions (window->window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
9157       
9158       box1 = gtk_vbox_new (FALSE, 0);
9159       gtk_container_add (GTK_CONTAINER (window), box1);
9160       gtk_widget_show (box1);
9161
9162       label = gtk_label_new ("Try iconizing me!");
9163       gtk_widget_set_usize (label, 150, 50);
9164       gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
9165       gtk_widget_show (label);
9166
9167
9168       separator = gtk_hseparator_new ();
9169       gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9170       gtk_widget_show (separator);
9171
9172
9173       box2 = gtk_vbox_new (FALSE, 10);
9174       gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9175       gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9176       gtk_widget_show (box2);
9177
9178
9179       button = gtk_button_new_with_label ("close");
9180
9181       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
9182                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9183                                  GTK_OBJECT (window));
9184
9185       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9186       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
9187       gtk_widget_grab_default (button);
9188       gtk_widget_show (button);
9189     }
9190
9191   if (!GTK_WIDGET_VISIBLE (window))
9192     gtk_widget_show (window);
9193   else
9194     gtk_widget_destroy (window);
9195 }
9196
9197
9198 /*
9199  * Window state tracking
9200  */
9201
9202 static gint
9203 window_state_callback (GtkWidget *widget,
9204                        GdkEventWindowState *event,
9205                        gpointer data)
9206 {
9207   GtkWidget *label = data;
9208   gchar *msg;
9209
9210   msg = g_strconcat (GTK_WINDOW (widget)->title, ": ",
9211                      (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
9212                      "withdrawn" : "not withdrawn", ", ",
9213                      (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
9214                      "iconified" : "not iconified", ", ",
9215                      (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
9216                      "sticky" : "not sticky", ", ",
9217                      (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
9218                      "maximized" : "not maximized", ", ",
9219                      (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
9220                      "fullscreen" : "not fullscreen",
9221                      NULL);
9222   
9223   gtk_label_set_text (GTK_LABEL (label), msg);
9224
9225   g_free (msg);
9226
9227   return FALSE;
9228 }
9229
9230 static GtkWidget*
9231 tracking_label (GtkWidget *window)
9232 {
9233   GtkWidget *label;
9234   GtkWidget *hbox;
9235   GtkWidget *button;
9236
9237   hbox = gtk_hbox_new (FALSE, 5);
9238
9239   gtk_signal_connect_object (GTK_OBJECT (hbox),
9240                              "destroy",
9241                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9242                              GTK_OBJECT (window));
9243   
9244   label = gtk_label_new ("<no window state events received>");
9245   gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
9246   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
9247   
9248   gtk_signal_connect (GTK_OBJECT (window),
9249                       "window_state_event",
9250                       GTK_SIGNAL_FUNC (window_state_callback),
9251                       label);
9252
9253   button = gtk_button_new_with_label ("Deiconify");
9254   gtk_signal_connect_object (GTK_OBJECT (button),
9255                              "clicked",
9256                              GTK_SIGNAL_FUNC (gtk_window_deiconify),
9257                              GTK_OBJECT (window));
9258   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9259
9260   button = gtk_button_new_with_label ("Iconify");
9261   gtk_signal_connect_object (GTK_OBJECT (button),
9262                              "clicked",
9263                              GTK_SIGNAL_FUNC (gtk_window_iconify),
9264                              GTK_OBJECT (window));
9265   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9266
9267   button = gtk_button_new_with_label ("Fullscreen");
9268   gtk_signal_connect_object (GTK_OBJECT (button),
9269                              "clicked",
9270                              GTK_SIGNAL_FUNC (gtk_window_fullscreen),
9271                              GTK_OBJECT (window));
9272   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9273
9274   button = gtk_button_new_with_label ("Unfullscreen");
9275   gtk_signal_connect_object (GTK_OBJECT (button),
9276                              "clicked",
9277                              GTK_SIGNAL_FUNC (gtk_window_unfullscreen),
9278                              GTK_OBJECT (window));
9279   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9280   
9281   button = gtk_button_new_with_label ("Present");
9282   gtk_signal_connect_object (GTK_OBJECT (button),
9283                              "clicked",
9284                              GTK_SIGNAL_FUNC (gtk_window_present),
9285                              GTK_OBJECT (window));
9286   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9287
9288   button = gtk_button_new_with_label ("Show");
9289   gtk_signal_connect_object (GTK_OBJECT (button),
9290                              "clicked",
9291                              GTK_SIGNAL_FUNC (gtk_widget_show),
9292                              GTK_OBJECT (window));
9293   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
9294   
9295   gtk_widget_show_all (hbox);
9296   
9297   return hbox;
9298 }
9299
9300 static GtkWidget*
9301 get_state_controls (GtkWidget *window)
9302 {
9303   GtkWidget *vbox;
9304   GtkWidget *button;
9305
9306   vbox = gtk_vbox_new (FALSE, 0);
9307   
9308   button = gtk_button_new_with_label ("Stick");
9309   gtk_signal_connect_object (GTK_OBJECT (button),
9310                              "clicked",
9311                              GTK_SIGNAL_FUNC (gtk_window_stick),
9312                              GTK_OBJECT (window));
9313   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9314
9315   button = gtk_button_new_with_label ("Unstick");
9316   gtk_signal_connect_object (GTK_OBJECT (button),
9317                              "clicked",
9318                              GTK_SIGNAL_FUNC (gtk_window_unstick),
9319                              GTK_OBJECT (window));
9320   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9321   
9322   button = gtk_button_new_with_label ("Maximize");
9323   gtk_signal_connect_object (GTK_OBJECT (button),
9324                              "clicked",
9325                              GTK_SIGNAL_FUNC (gtk_window_maximize),
9326                              GTK_OBJECT (window));
9327   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9328
9329   button = gtk_button_new_with_label ("Unmaximize");
9330   gtk_signal_connect_object (GTK_OBJECT (button),
9331                              "clicked",
9332                              GTK_SIGNAL_FUNC (gtk_window_unmaximize),
9333                              GTK_OBJECT (window));
9334   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9335
9336   button = gtk_button_new_with_label ("Iconify");
9337   gtk_signal_connect_object (GTK_OBJECT (button),
9338                              "clicked",
9339                              GTK_SIGNAL_FUNC (gtk_window_iconify),
9340                              GTK_OBJECT (window));
9341   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9342
9343   button = gtk_button_new_with_label ("Fullscreen");
9344   gtk_signal_connect_object (GTK_OBJECT (button),
9345                              "clicked",
9346                              GTK_SIGNAL_FUNC (gtk_window_fullscreen),
9347                              GTK_OBJECT (window));
9348   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9349
9350   button = gtk_button_new_with_label ("Unfullscreen");
9351   gtk_signal_connect_object (GTK_OBJECT (button),
9352                              "clicked",
9353                              GTK_SIGNAL_FUNC (gtk_window_unfullscreen),
9354                              GTK_OBJECT (window));
9355   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9356   
9357   button = gtk_button_new_with_label ("Hide (withdraw)");
9358   gtk_signal_connect_object (GTK_OBJECT (button),
9359                              "clicked",
9360                              GTK_SIGNAL_FUNC (gtk_widget_hide),
9361                              GTK_OBJECT (window));
9362   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9363   
9364   gtk_widget_show_all (vbox);
9365
9366   return vbox;
9367 }
9368
9369 void
9370 create_window_states (GtkWidget *widget)
9371 {
9372   static GtkWidget *window = NULL;
9373   GtkWidget *label;
9374   GtkWidget *box1;
9375   GtkWidget *iconified;
9376   GtkWidget *normal;
9377   GtkWidget *controls;
9378
9379   if (!window)
9380     {
9381       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9382       gtk_window_set_screen (GTK_WINDOW (window),
9383                              gtk_widget_get_screen (widget));
9384
9385       gtk_signal_connect (GTK_OBJECT (window), "destroy",
9386                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
9387                           &window);
9388
9389       gtk_window_set_title (GTK_WINDOW (window), "Window states");
9390       
9391       box1 = gtk_vbox_new (FALSE, 0);
9392       gtk_container_add (GTK_CONTAINER (window), box1);
9393
9394       iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9395
9396       gtk_window_set_screen (GTK_WINDOW (iconified),
9397                              gtk_widget_get_screen (widget));
9398       
9399       gtk_signal_connect_object (GTK_OBJECT (iconified), "destroy",
9400                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9401                                  GTK_OBJECT (window));
9402       gtk_window_iconify (GTK_WINDOW (iconified));
9403       gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
9404       controls = get_state_controls (iconified);
9405       gtk_container_add (GTK_CONTAINER (iconified), controls);
9406       
9407       normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9408
9409       gtk_window_set_screen (GTK_WINDOW (normal),
9410                              gtk_widget_get_screen (widget));
9411       
9412       gtk_signal_connect_object (GTK_OBJECT (normal), "destroy",
9413                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
9414                                  GTK_OBJECT (window));
9415       
9416       gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
9417       controls = get_state_controls (normal);
9418       gtk_container_add (GTK_CONTAINER (normal), controls);
9419       
9420       label = tracking_label (iconified);
9421       gtk_container_add (GTK_CONTAINER (box1), label);
9422
9423       label = tracking_label (normal);
9424       gtk_container_add (GTK_CONTAINER (box1), label);
9425
9426       gtk_widget_show_all (iconified);
9427       gtk_widget_show_all (normal);
9428       gtk_widget_show_all (box1);
9429     }
9430
9431   if (!GTK_WIDGET_VISIBLE (window))
9432     gtk_widget_show (window);
9433   else
9434     gtk_widget_destroy (window);
9435 }
9436
9437 /*
9438  * Window sizing
9439  */
9440
9441 static gint
9442 configure_event_callback (GtkWidget *widget,
9443                           GdkEventConfigure *event,
9444                           gpointer data)
9445 {
9446   GtkWidget *label = data;
9447   gchar *msg;
9448   gint x, y;
9449   
9450   gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
9451   
9452   msg = g_strdup_printf ("event: %d,%d  %d x %d\n"
9453                          "position: %d, %d",
9454                          event->x, event->y, event->width, event->height,
9455                          x, y);
9456   
9457   gtk_label_set_text (GTK_LABEL (label), msg);
9458
9459   g_free (msg);
9460
9461   return FALSE;
9462 }
9463
9464 static void
9465 get_ints (GtkWidget *window,
9466           gint      *a,
9467           gint      *b)
9468 {
9469   GtkWidget *spin1;
9470   GtkWidget *spin2;
9471
9472   spin1 = g_object_get_data (G_OBJECT (window), "spin1");
9473   spin2 = g_object_get_data (G_OBJECT (window), "spin2");
9474
9475   *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
9476   *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
9477 }
9478
9479 static void
9480 set_size_callback (GtkWidget *widget,
9481                    gpointer   data)
9482 {
9483   gint w, h;
9484   
9485   get_ints (data, &w, &h);
9486
9487   gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
9488 }
9489
9490 static void
9491 unset_default_size_callback (GtkWidget *widget,
9492                              gpointer   data)
9493 {
9494   gtk_window_set_default_size (g_object_get_data (data, "target"),
9495                                -1, -1);
9496 }
9497
9498 static void
9499 set_default_size_callback (GtkWidget *widget,
9500                            gpointer   data)
9501 {
9502   gint w, h;
9503   
9504   get_ints (data, &w, &h);
9505
9506   gtk_window_set_default_size (g_object_get_data (data, "target"),
9507                                w, h);
9508 }
9509
9510 static void
9511 unset_usize_callback (GtkWidget *widget,
9512                       gpointer   data)
9513 {
9514   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9515                                -1, -1);
9516 }
9517
9518 static void
9519 set_usize_callback (GtkWidget *widget,
9520                     gpointer   data)
9521 {
9522   gint w, h;
9523   
9524   get_ints (data, &w, &h);
9525
9526   gtk_widget_set_size_request (g_object_get_data (data, "target"),
9527                                w, h);
9528 }
9529
9530 static void
9531 set_location_callback (GtkWidget *widget,
9532                        gpointer   data)
9533 {
9534   gint x, y;
9535   
9536   get_ints (data, &x, &y);
9537
9538   gtk_window_move (g_object_get_data (data, "target"), x, y);
9539 }
9540
9541 static void
9542 move_to_position_callback (GtkWidget *widget,
9543                            gpointer   data)
9544 {
9545   gint x, y;
9546   GtkWindow *window;
9547
9548   window = g_object_get_data (data, "target");
9549   
9550   gtk_window_get_position (window, &x, &y);
9551
9552   gtk_window_move (window, x, y);
9553 }
9554
9555 static void
9556 set_geometry_callback (GtkWidget *entry,
9557                        gpointer   data)
9558 {
9559   gchar *text;
9560   GtkWindow *target;
9561
9562   target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
9563   
9564   text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
9565
9566   if (!gtk_window_parse_geometry (target, text))
9567     g_print ("Bad geometry string '%s'\n", text);
9568
9569   g_free (text);
9570 }
9571
9572 static void
9573 allow_shrink_callback (GtkWidget *widget,
9574                        gpointer   data)
9575 {
9576   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9577                 "allow_shrink",
9578                 GTK_TOGGLE_BUTTON (widget)->active,
9579                 NULL);
9580 }
9581
9582 static void
9583 allow_grow_callback (GtkWidget *widget,
9584                      gpointer   data)
9585 {
9586   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9587                 "allow_grow",
9588                 GTK_TOGGLE_BUTTON (widget)->active,
9589                 NULL);
9590 }
9591
9592 static void
9593 auto_shrink_callback (GtkWidget *widget,
9594                       gpointer   data)
9595 {
9596   g_object_set (G_OBJECT (g_object_get_data (data, "target")),
9597                 "auto_shrink",
9598                 GTK_TOGGLE_BUTTON (widget)->active,
9599                 NULL);
9600 }
9601
9602 static void
9603 gravity_selected (GtkWidget *widget,
9604                   gpointer   data)
9605 {
9606   gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
9607                           gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GDK_GRAVITY_NORTH_WEST);
9608 }
9609
9610 static void
9611 pos_selected (GtkWidget *widget,
9612               gpointer   data)
9613 {
9614   gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
9615                            gtk_option_menu_get_history (GTK_OPTION_MENU (widget)) + GTK_WIN_POS_NONE);
9616 }
9617
9618 static void
9619 move_gravity_window_to_current_position (GtkWidget *widget,
9620                                          gpointer   data)
9621 {
9622   gint x, y;
9623   GtkWindow *window;
9624
9625   window = GTK_WINDOW (data);    
9626   
9627   gtk_window_get_position (window, &x, &y);
9628
9629   gtk_window_move (window, x, y);
9630 }
9631
9632 static void
9633 get_screen_corner (GtkWindow *window,
9634                    gint      *x,
9635                    gint      *y)
9636 {
9637   int w, h;
9638   GdkScreen * screen = gtk_window_get_screen (window);
9639   
9640   gtk_window_get_size (GTK_WINDOW (window), &w, &h);
9641
9642   switch (gtk_window_get_gravity (window))
9643     {
9644     case GDK_GRAVITY_SOUTH_EAST:
9645       *x = gdk_screen_get_width (screen) - w;
9646       *y = gdk_screen_get_height (screen) - h;
9647       break;
9648
9649     case GDK_GRAVITY_NORTH_EAST:
9650       *x = gdk_screen_get_width (screen) - w;
9651       *y = 0;
9652       break;
9653
9654     case GDK_GRAVITY_SOUTH_WEST:
9655       *x = 0;
9656       *y = gdk_screen_get_height (screen) - h;
9657       break;
9658
9659     case GDK_GRAVITY_NORTH_WEST:
9660       *x = 0;
9661       *y = 0;
9662       break;
9663       
9664     case GDK_GRAVITY_SOUTH:
9665       *x = (gdk_screen_get_width (screen) - w) / 2;
9666       *y = gdk_screen_get_height (screen) - h;
9667       break;
9668
9669     case GDK_GRAVITY_NORTH:
9670       *x = (gdk_screen_get_width (screen) - w) / 2;
9671       *y = 0;
9672       break;
9673
9674     case GDK_GRAVITY_WEST:
9675       *x = 0;
9676       *y = (gdk_screen_get_height (screen) - h) / 2;
9677       break;
9678
9679     case GDK_GRAVITY_EAST:
9680       *x = gdk_screen_get_width (screen) - w;
9681       *y = (gdk_screen_get_height (screen) - h) / 2;
9682       break;
9683
9684     case GDK_GRAVITY_CENTER:
9685       *x = (gdk_screen_get_width (screen) - w) / 2;
9686       *y = (gdk_screen_get_height (screen) - h) / 2;
9687       break;
9688
9689     case GDK_GRAVITY_STATIC:
9690       /* pick some random numbers */
9691       *x = 350;
9692       *y = 350;
9693       break;
9694
9695     default:
9696       g_assert_not_reached ();
9697       break;
9698     }
9699 }
9700
9701 static void
9702 move_gravity_window_to_starting_position (GtkWidget *widget,
9703                                           gpointer   data)
9704 {
9705   gint x, y;
9706   GtkWindow *window;
9707
9708   window = GTK_WINDOW (data);    
9709   
9710   get_screen_corner (window,
9711                      &x, &y);
9712   
9713   gtk_window_move (window, x, y);
9714 }
9715
9716 static GtkWidget*
9717 make_gravity_window (GtkWidget   *destroy_with,
9718                      GdkGravity   gravity,
9719                      const gchar *title)
9720 {
9721   GtkWidget *window;
9722   GtkWidget *button;
9723   GtkWidget *vbox;
9724   int x, y;
9725   
9726   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9727
9728   gtk_window_set_screen (GTK_WINDOW (window),
9729                          gtk_widget_get_screen (destroy_with));
9730
9731   vbox = gtk_vbox_new (FALSE, 0);
9732   gtk_widget_show (vbox);
9733   
9734   gtk_container_add (GTK_CONTAINER (window), vbox);
9735   gtk_window_set_title (GTK_WINDOW (window), title);
9736   gtk_window_set_gravity (GTK_WINDOW (window), gravity);
9737
9738   gtk_signal_connect_object (GTK_OBJECT (destroy_with),
9739                              "destroy",
9740                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9741                              GTK_OBJECT (window));
9742
9743   
9744   button = gtk_button_new_with_mnemonic ("_Move to current position");
9745
9746   g_signal_connect (G_OBJECT (button), "clicked",
9747                     G_CALLBACK (move_gravity_window_to_current_position),
9748                     window);
9749
9750   gtk_container_add (GTK_CONTAINER (vbox), button);
9751   gtk_widget_show (button);
9752
9753   button = gtk_button_new_with_mnemonic ("Move to _starting position");
9754
9755   g_signal_connect (G_OBJECT (button), "clicked",
9756                     G_CALLBACK (move_gravity_window_to_starting_position),
9757                     window);
9758
9759   gtk_container_add (GTK_CONTAINER (vbox), button);
9760   gtk_widget_show (button);
9761   
9762   /* Pretend this is the result of --geometry.
9763    * DO NOT COPY THIS CODE unless you are setting --geometry results,
9764    * and in that case you probably should just use gtk_window_parse_geometry().
9765    * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
9766    * you are parsing --geometry or equivalent.
9767    */
9768   gtk_window_set_geometry_hints (GTK_WINDOW (window),
9769                                  NULL, NULL,
9770                                  GDK_HINT_USER_POS);
9771
9772   gtk_window_set_default_size (GTK_WINDOW (window),
9773                                200, 200);
9774
9775   get_screen_corner (GTK_WINDOW (window), &x, &y);
9776   
9777   gtk_window_move (GTK_WINDOW (window),
9778                    x, y);
9779   
9780   return window;
9781 }
9782
9783 static void
9784 do_gravity_test (GtkWidget *widget,
9785                  gpointer   data)
9786 {
9787   GtkWidget *destroy_with = data;
9788   GtkWidget *window;
9789   
9790   /* We put a window at each gravity point on the screen. */
9791   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
9792                                 "NorthWest");
9793   gtk_widget_show (window);
9794   
9795   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
9796                                 "SouthEast");
9797   gtk_widget_show (window);
9798
9799   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
9800                                 "NorthEast");
9801   gtk_widget_show (window);
9802
9803   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
9804                                 "SouthWest");
9805   gtk_widget_show (window);
9806
9807   window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
9808                                 "South");
9809   gtk_widget_show (window);
9810
9811   window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
9812                                 "North");
9813   gtk_widget_show (window);
9814
9815   
9816   window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
9817                                 "West");
9818   gtk_widget_show (window);
9819
9820     
9821   window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
9822                                 "East");
9823   gtk_widget_show (window);
9824
9825   window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
9826                                 "Center");
9827   gtk_widget_show (window);
9828
9829   window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
9830                                 "Static");
9831   gtk_widget_show (window);
9832 }
9833
9834 static GtkWidget*
9835 window_controls (GtkWidget *window)
9836 {
9837   GtkWidget *control_window;
9838   GtkWidget *label;
9839   GtkWidget *vbox;
9840   GtkWidget *button;
9841   GtkWidget *spin;
9842   GtkAdjustment *adj;
9843   GtkWidget *entry;
9844   GtkWidget *om;
9845   GtkWidget *menu;
9846   gint i;
9847   
9848   control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9849
9850   gtk_window_set_screen (GTK_WINDOW (control_window),
9851                          gtk_widget_get_screen (window));
9852
9853   gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
9854   
9855   g_object_set_data (G_OBJECT (control_window),
9856                      "target",
9857                      window);
9858   
9859   gtk_signal_connect_object (GTK_OBJECT (control_window),
9860                              "destroy",
9861                              GTK_SIGNAL_FUNC (gtk_widget_destroy),
9862                              GTK_OBJECT (window));
9863
9864   vbox = gtk_vbox_new (FALSE, 5);
9865   
9866   gtk_container_add (GTK_CONTAINER (control_window), vbox);
9867   
9868   label = gtk_label_new ("<no configure events>");
9869   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
9870   
9871   gtk_signal_connect (GTK_OBJECT (window),
9872                       "configure_event",
9873                       GTK_SIGNAL_FUNC (configure_event_callback),
9874                       label);
9875
9876   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9877                                               5.0, 0.0);
9878   spin = gtk_spin_button_new (adj, 0, 0);
9879
9880   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9881
9882   g_object_set_data (G_OBJECT (control_window), "spin1", spin);
9883
9884   adj = (GtkAdjustment *) gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0,
9885                                               5.0, 0.0);
9886   spin = gtk_spin_button_new (adj, 0, 0);
9887
9888   gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
9889
9890   g_object_set_data (G_OBJECT (control_window), "spin2", spin);
9891
9892   entry = gtk_entry_new ();
9893   gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
9894
9895   gtk_signal_connect (GTK_OBJECT (entry), "changed",
9896                       GTK_SIGNAL_FUNC (set_geometry_callback),
9897                       control_window);
9898
9899   button = gtk_button_new_with_label ("Show gravity test windows");
9900   gtk_signal_connect_object (GTK_OBJECT (button),
9901                              "clicked",
9902                              GTK_SIGNAL_FUNC (do_gravity_test),
9903                              control_window);
9904   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9905
9906   button = gtk_button_new_with_label ("Reshow with initial size");
9907   gtk_signal_connect_object (GTK_OBJECT (button),
9908                              "clicked",
9909                              GTK_SIGNAL_FUNC (gtk_window_reshow_with_initial_size),
9910                              GTK_OBJECT (window));
9911   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9912   
9913   button = gtk_button_new_with_label ("Queue resize");
9914   gtk_signal_connect_object (GTK_OBJECT (button),
9915                              "clicked",
9916                              GTK_SIGNAL_FUNC (gtk_widget_queue_resize),
9917                              GTK_OBJECT (window));
9918   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9919   
9920   button = gtk_button_new_with_label ("Resize");
9921   gtk_signal_connect (GTK_OBJECT (button),
9922                       "clicked",
9923                       GTK_SIGNAL_FUNC (set_size_callback),
9924                       GTK_OBJECT (control_window));
9925   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9926
9927   button = gtk_button_new_with_label ("Set default size");
9928   gtk_signal_connect (GTK_OBJECT (button),
9929                       "clicked",
9930                       GTK_SIGNAL_FUNC (set_default_size_callback),
9931                       GTK_OBJECT (control_window));
9932   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9933
9934   button = gtk_button_new_with_label ("Unset default size");
9935   gtk_signal_connect (GTK_OBJECT (button),
9936                       "clicked",
9937                       GTK_SIGNAL_FUNC (unset_default_size_callback),
9938                       GTK_OBJECT (control_window));
9939   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9940   
9941   button = gtk_button_new_with_label ("Set size request");
9942   gtk_signal_connect (GTK_OBJECT (button),
9943                       "clicked",
9944                       GTK_SIGNAL_FUNC (set_usize_callback),
9945                       GTK_OBJECT (control_window));
9946   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9947
9948   button = gtk_button_new_with_label ("Unset size request");
9949   gtk_signal_connect (GTK_OBJECT (button),
9950                       "clicked",
9951                       GTK_SIGNAL_FUNC (unset_usize_callback),
9952                       GTK_OBJECT (control_window));
9953   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9954   
9955   button = gtk_button_new_with_label ("Move");
9956   gtk_signal_connect (GTK_OBJECT (button),
9957                       "clicked",
9958                       GTK_SIGNAL_FUNC (set_location_callback),
9959                       GTK_OBJECT (control_window));
9960   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9961
9962   button = gtk_button_new_with_label ("Move to current position");
9963   gtk_signal_connect (GTK_OBJECT (button),
9964                       "clicked",
9965                       GTK_SIGNAL_FUNC (move_to_position_callback),
9966                       GTK_OBJECT (control_window));
9967   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9968   
9969   button = gtk_check_button_new_with_label ("Allow shrink");
9970   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9971   gtk_signal_connect (GTK_OBJECT (button),
9972                       "toggled",
9973                       GTK_SIGNAL_FUNC (allow_shrink_callback),
9974                       GTK_OBJECT (control_window));
9975   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9976
9977   button = gtk_check_button_new_with_label ("Allow grow");
9978   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
9979   gtk_signal_connect (GTK_OBJECT (button),
9980                       "toggled",
9981                       GTK_SIGNAL_FUNC (allow_grow_callback),
9982                       GTK_OBJECT (control_window));
9983   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9984   
9985   button = gtk_check_button_new_with_label ("Auto shrink");
9986   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
9987   gtk_signal_connect (GTK_OBJECT (button),
9988                       "toggled",
9989                       GTK_SIGNAL_FUNC (auto_shrink_callback),
9990                       GTK_OBJECT (control_window));
9991   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9992
9993   button = gtk_button_new_with_mnemonic ("_Show");
9994   gtk_signal_connect_object (GTK_OBJECT (button),
9995                              "clicked",
9996                              GTK_SIGNAL_FUNC (gtk_widget_show),
9997                              GTK_OBJECT (window));
9998   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
9999
10000   button = gtk_button_new_with_mnemonic ("_Hide");
10001   gtk_signal_connect_object (GTK_OBJECT (button),
10002                              "clicked",
10003                              GTK_SIGNAL_FUNC (gtk_widget_hide),
10004                              GTK_OBJECT (window));
10005   gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
10006   
10007   menu = gtk_menu_new ();
10008   
10009   i = 0;
10010   while (i < 10)
10011     {
10012       GtkWidget *mi;
10013       static gchar *names[] = {
10014         "GDK_GRAVITY_NORTH_WEST",
10015         "GDK_GRAVITY_NORTH",
10016         "GDK_GRAVITY_NORTH_EAST",
10017         "GDK_GRAVITY_WEST",
10018         "GDK_GRAVITY_CENTER",
10019         "GDK_GRAVITY_EAST",
10020         "GDK_GRAVITY_SOUTH_WEST",
10021         "GDK_GRAVITY_SOUTH",
10022         "GDK_GRAVITY_SOUTH_EAST",
10023         "GDK_GRAVITY_STATIC",
10024         NULL
10025       };
10026
10027       g_assert (names[i]);
10028       
10029       mi = gtk_menu_item_new_with_label (names[i]);
10030
10031       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10032
10033       ++i;
10034     }
10035   
10036   gtk_widget_show_all (menu);
10037   
10038   om = gtk_option_menu_new ();
10039   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10040   
10041
10042   gtk_signal_connect (GTK_OBJECT (om),
10043                       "changed",
10044                       GTK_SIGNAL_FUNC (gravity_selected),
10045                       control_window);
10046
10047   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10048
10049
10050   menu = gtk_menu_new ();
10051   
10052   i = 0;
10053   while (i < 5)
10054     {
10055       GtkWidget *mi;
10056       static gchar *names[] = {
10057         "GTK_WIN_POS_NONE",
10058         "GTK_WIN_POS_CENTER",
10059         "GTK_WIN_POS_MOUSE",
10060         "GTK_WIN_POS_CENTER_ALWAYS",
10061         "GTK_WIN_POS_CENTER_ON_PARENT",
10062         NULL
10063       };
10064
10065       g_assert (names[i]);
10066       
10067       mi = gtk_menu_item_new_with_label (names[i]);
10068
10069       gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
10070
10071       ++i;
10072     }
10073   
10074   gtk_widget_show_all (menu);
10075   
10076   om = gtk_option_menu_new ();
10077   gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
10078   
10079
10080   gtk_signal_connect (GTK_OBJECT (om),
10081                       "changed",
10082                       GTK_SIGNAL_FUNC (pos_selected),
10083                       control_window);
10084
10085   gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
10086   
10087   gtk_widget_show_all (vbox);
10088   
10089   return control_window;
10090 }
10091
10092 void
10093 create_window_sizing (GtkWidget *widget)
10094 {
10095   static GtkWidget *window = NULL;
10096   static GtkWidget *target_window = NULL;
10097
10098   if (!target_window)
10099     {
10100       GtkWidget *label;
10101       
10102       target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10103       gtk_window_set_screen (GTK_WINDOW (target_window),
10104                              gtk_widget_get_screen (widget));
10105       label = gtk_label_new (NULL);
10106       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");
10107       gtk_container_add (GTK_CONTAINER (target_window), label);
10108       gtk_widget_show (label);
10109       
10110       gtk_signal_connect (GTK_OBJECT (target_window), "destroy",
10111                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
10112                           &target_window);
10113
10114       window = window_controls (target_window);
10115       
10116       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10117                           GTK_SIGNAL_FUNC (gtk_widget_destroyed),
10118                           &window);
10119       
10120       gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
10121     }
10122
10123   /* don't show target window by default, we want to allow testing
10124    * of behavior on first show.
10125    */
10126   
10127   if (!GTK_WIDGET_VISIBLE (window))
10128     gtk_widget_show (window);
10129   else
10130     gtk_widget_destroy (window);
10131 }
10132
10133 /*
10134  * GtkProgressBar
10135  */
10136
10137 typedef struct _ProgressData {
10138   GtkWidget *window;
10139   GtkWidget *pbar;
10140   GtkWidget *block_spin;
10141   GtkWidget *x_align_spin;
10142   GtkWidget *y_align_spin;
10143   GtkWidget *step_spin;
10144   GtkWidget *act_blocks_spin;
10145   GtkWidget *label;
10146   GtkWidget *omenu1;
10147   GtkWidget *omenu2;
10148   GtkWidget *entry;
10149   int timer;
10150 } ProgressData;
10151
10152 gint
10153 progress_timeout (gpointer data)
10154 {
10155   gdouble new_val;
10156   GtkAdjustment *adj;
10157
10158   adj = GTK_PROGRESS (data)->adjustment;
10159
10160   new_val = adj->value + 1;
10161   if (new_val > adj->upper)
10162     new_val = adj->lower;
10163
10164   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
10165
10166   return TRUE;
10167 }
10168
10169 static void
10170 destroy_progress (GtkWidget     *widget,
10171                   ProgressData **pdata)
10172 {
10173   gtk_timeout_remove ((*pdata)->timer);
10174   (*pdata)->timer = 0;
10175   (*pdata)->window = NULL;
10176   g_free (*pdata);
10177   *pdata = NULL;
10178 }
10179
10180 static void
10181 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
10182 {
10183   ProgressData *pdata;
10184   gint i;
10185
10186   pdata = (ProgressData *) data;
10187
10188   if (!GTK_WIDGET_MAPPED (widget))
10189     return;
10190
10191   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10192
10193   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
10194                                     (GtkProgressBarOrientation) i);
10195 }
10196
10197 static void
10198 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
10199 {
10200   gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
10201                               GTK_TOGGLE_BUTTON (widget)->active);
10202   gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
10203   gtk_widget_set_sensitive (pdata->x_align_spin,
10204                             GTK_TOGGLE_BUTTON (widget)->active);
10205   gtk_widget_set_sensitive (pdata->y_align_spin,
10206                             GTK_TOGGLE_BUTTON (widget)->active);
10207 }
10208
10209 static void
10210 progressbar_toggle_bar_style (GtkWidget *widget, gpointer data)
10211 {
10212   ProgressData *pdata;
10213   gint i;
10214
10215   pdata = (ProgressData *) data;
10216
10217   if (!GTK_WIDGET_MAPPED (widget))
10218     return;
10219
10220   i = gtk_option_menu_get_history (GTK_OPTION_MENU (widget));
10221
10222   if (i == 1)
10223     gtk_widget_set_sensitive (pdata->block_spin, TRUE);
10224   else
10225     gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10226   
10227   gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
10228                                   (GtkProgressBarStyle) i);
10229 }
10230
10231 static void
10232 progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
10233 {
10234   char buf[20];
10235
10236   if (GTK_PROGRESS (pdata->pbar)->activity_mode)
10237     sprintf (buf, "???");
10238   else
10239     sprintf (buf, "%.0f%%", 100 *
10240              gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
10241   gtk_label_set_text (GTK_LABEL (pdata->label), buf);
10242 }
10243
10244 static void
10245 adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
10246 {
10247   gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
10248   gtk_progress_bar_set_discrete_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10249      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
10250 }
10251
10252 static void
10253 adjust_step (GtkAdjustment *adj, ProgressData *pdata)
10254 {
10255   gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
10256      gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
10257 }
10258
10259 static void
10260 adjust_act_blocks (GtkAdjustment *adj, ProgressData *pdata)
10261 {
10262   gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (pdata->pbar),
10263                gtk_spin_button_get_value_as_int 
10264                       (GTK_SPIN_BUTTON (pdata->act_blocks_spin)));
10265 }
10266
10267 static void
10268 adjust_align (GtkAdjustment *adj, ProgressData *pdata)
10269 {
10270   gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
10271          gtk_spin_button_get_value_as_float 
10272                                    (GTK_SPIN_BUTTON (pdata->x_align_spin)),
10273          gtk_spin_button_get_value_as_float
10274                                    (GTK_SPIN_BUTTON (pdata->y_align_spin)));
10275 }
10276
10277 static void
10278 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
10279 {
10280   gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
10281                                   GTK_TOGGLE_BUTTON (widget)->active);
10282   gtk_widget_set_sensitive (pdata->step_spin, 
10283                             GTK_TOGGLE_BUTTON (widget)->active);
10284   gtk_widget_set_sensitive (pdata->act_blocks_spin, 
10285                             GTK_TOGGLE_BUTTON (widget)->active);
10286 }
10287
10288 static void
10289 entry_changed (GtkWidget *widget, ProgressData *pdata)
10290 {
10291   gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10292                           gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
10293 }
10294
10295 void
10296 create_progress_bar (GtkWidget *widget)
10297 {
10298   GtkWidget *button;
10299   GtkWidget *vbox;
10300   GtkWidget *vbox2;
10301   GtkWidget *hbox;
10302   GtkWidget *check;
10303   GtkWidget *frame;
10304   GtkWidget *tab;
10305   GtkWidget *label;
10306   GtkWidget *align;
10307   GtkAdjustment *adj;
10308   static ProgressData *pdata = NULL;
10309
10310   static gchar *items1[] =
10311   {
10312     "Left-Right",
10313     "Right-Left",
10314     "Bottom-Top",
10315     "Top-Bottom"
10316   };
10317
10318   static gchar *items2[] =
10319   {
10320     "Continuous",
10321     "Discrete"
10322   };
10323   
10324   if (!pdata)
10325     pdata = g_new0 (ProgressData, 1);
10326
10327   if (!pdata->window)
10328     {
10329       pdata->window = gtk_dialog_new ();
10330
10331       gtk_window_set_screen (GTK_WINDOW (pdata->window),
10332                              gtk_widget_get_screen (widget));
10333
10334       gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
10335
10336       gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
10337                           GTK_SIGNAL_FUNC (destroy_progress),
10338                           &pdata);
10339
10340       pdata->timer = 0;
10341
10342       gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
10343       gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
10344
10345       vbox = gtk_vbox_new (FALSE, 5);
10346       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
10347       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
10348                           vbox, FALSE, TRUE, 0);
10349
10350       frame = gtk_frame_new ("Progress");
10351       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10352
10353       vbox2 = gtk_vbox_new (FALSE, 5);
10354       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10355
10356       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10357       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10358
10359       adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
10360       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10361                           GTK_SIGNAL_FUNC (progress_value_changed), pdata);
10362
10363       pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
10364       gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
10365                                       "%v from [%l,%u] (=%p%%)");
10366       gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
10367       pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
10368
10369       align = gtk_alignment_new (0.5, 0.5, 0, 0);
10370       gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
10371
10372       hbox = gtk_hbox_new (FALSE, 5);
10373       gtk_container_add (GTK_CONTAINER (align), hbox);
10374       label = gtk_label_new ("Label updated by user :"); 
10375       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10376       pdata->label = gtk_label_new ("");
10377       gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
10378
10379       frame = gtk_frame_new ("Options");
10380       gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
10381
10382       vbox2 = gtk_vbox_new (FALSE, 5);
10383       gtk_container_add (GTK_CONTAINER (frame), vbox2);
10384
10385       tab = gtk_table_new (7, 2, FALSE);
10386       gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
10387
10388       label = gtk_label_new ("Orientation :");
10389       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
10390                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10391                         5, 5);
10392       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10393
10394       pdata->omenu1 = build_option_menu (items1, 4, 0,
10395                                          progressbar_toggle_orientation,
10396                                          pdata);
10397       hbox = gtk_hbox_new (FALSE, 0);
10398       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
10399                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10400                         5, 5);
10401       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
10402       
10403       check = gtk_check_button_new_with_label ("Show text");
10404       gtk_signal_connect (GTK_OBJECT (check), "clicked",
10405                           GTK_SIGNAL_FUNC (toggle_show_text),
10406                           pdata);
10407       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
10408                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10409                         5, 5);
10410
10411       hbox = gtk_hbox_new (FALSE, 0);
10412       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
10413                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10414                         5, 5);
10415
10416       label = gtk_label_new ("Format : ");
10417       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10418
10419       pdata->entry = gtk_entry_new ();
10420       gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
10421                           GTK_SIGNAL_FUNC (entry_changed),
10422                           pdata);
10423       gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
10424       gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
10425       gtk_widget_set_usize (pdata->entry, 100, -1);
10426       gtk_widget_set_sensitive (pdata->entry, FALSE);
10427
10428       label = gtk_label_new ("Text align :");
10429       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
10430                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10431                         5, 5);
10432       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10433
10434       hbox = gtk_hbox_new (FALSE, 0);
10435       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
10436                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10437                         5, 5);
10438
10439       label = gtk_label_new ("x :");
10440       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10441       
10442       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10443       pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
10444       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10445                           GTK_SIGNAL_FUNC (adjust_align), pdata);
10446       gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
10447       gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
10448
10449       label = gtk_label_new ("y :");
10450       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
10451
10452       adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
10453       pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
10454       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10455                           GTK_SIGNAL_FUNC (adjust_align), pdata);
10456       gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
10457       gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
10458
10459       label = gtk_label_new ("Bar Style :");
10460       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
10461                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10462                         5, 5);
10463       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10464
10465       pdata->omenu2 = build_option_menu (items2, 2, 0,
10466                                          progressbar_toggle_bar_style,
10467                                          pdata);
10468       hbox = gtk_hbox_new (FALSE, 0);
10469       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
10470                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10471                         5, 5);
10472       gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu2, TRUE, TRUE, 0);
10473
10474       label = gtk_label_new ("Block count :");
10475       gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
10476                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10477                         5, 5);
10478       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
10479
10480       hbox = gtk_hbox_new (FALSE, 0);
10481       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
10482                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10483                         5, 5);
10484       adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
10485       pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
10486       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10487                           GTK_SIGNAL_FUNC (adjust_blocks), pdata);
10488       gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
10489       gtk_widget_set_sensitive (pdata->block_spin, FALSE);
10490
10491       check = gtk_check_button_new_with_label ("Activity mode");
10492       gtk_signal_connect (GTK_OBJECT (check), "clicked",
10493                           GTK_SIGNAL_FUNC (toggle_activity_mode),
10494                           pdata);
10495       gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
10496                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10497                         5, 5);
10498
10499       hbox = gtk_hbox_new (FALSE, 0);
10500       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
10501                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10502                         5, 5);
10503       label = gtk_label_new ("Step size : ");
10504       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10505       adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
10506       pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
10507       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10508                           GTK_SIGNAL_FUNC (adjust_step), pdata);
10509       gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
10510       gtk_widget_set_sensitive (pdata->step_spin, FALSE);
10511
10512       hbox = gtk_hbox_new (FALSE, 0);
10513       gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 6, 7,
10514                         GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
10515                         5, 5);
10516       label = gtk_label_new ("Blocks :     ");
10517       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
10518       adj = (GtkAdjustment *) gtk_adjustment_new (5, 2, 10, 1, 5, 0);
10519       pdata->act_blocks_spin = gtk_spin_button_new (adj, 0, 0);
10520       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
10521                           GTK_SIGNAL_FUNC (adjust_act_blocks), pdata);
10522       gtk_box_pack_start (GTK_BOX (hbox), pdata->act_blocks_spin, FALSE, TRUE,
10523                           0);
10524       gtk_widget_set_sensitive (pdata->act_blocks_spin, FALSE);
10525
10526       button = gtk_button_new_with_label ("close");
10527       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
10528                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
10529                                  GTK_OBJECT (pdata->window));
10530       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
10531       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
10532                           button, TRUE, TRUE, 0);
10533       gtk_widget_grab_default (button);
10534     }
10535
10536   if (!GTK_WIDGET_VISIBLE (pdata->window))
10537     gtk_widget_show_all (pdata->window);
10538   else
10539     gtk_widget_destroy (pdata->window);
10540 }
10541
10542 /*
10543  * Properties
10544  */
10545
10546 typedef struct {
10547   int x;
10548   int y;
10549   gboolean found;
10550   gboolean first;
10551   GtkWidget *res_widget;
10552 } FindWidgetData;
10553
10554 static void
10555 find_widget (GtkWidget *widget, FindWidgetData *data)
10556 {
10557   GtkAllocation new_allocation;
10558   gint x_offset = 0;
10559   gint y_offset = 0;
10560
10561   new_allocation = widget->allocation;
10562
10563   if (data->found || !GTK_WIDGET_MAPPED (widget))
10564     return;
10565
10566   /* Note that in the following code, we only count the
10567    * position as being inside a WINDOW widget if it is inside
10568    * widget->window; points that are outside of widget->window
10569    * but within the allocation are not counted. This is consistent
10570    * with the way we highlight drag targets.
10571    */
10572   if (!GTK_WIDGET_NO_WINDOW (widget))
10573     {
10574       new_allocation.x = 0;
10575       new_allocation.y = 0;
10576     }
10577   
10578   if (widget->parent && !data->first)
10579     {
10580       GdkWindow *window = widget->window;
10581       while (window != widget->parent->window)
10582         {
10583           gint tx, ty, twidth, theight;
10584           gdk_window_get_size (window, &twidth, &theight);
10585
10586           if (new_allocation.x < 0)
10587             {
10588               new_allocation.width += new_allocation.x;
10589               new_allocation.x = 0;
10590             }
10591           if (new_allocation.y < 0)
10592             {
10593               new_allocation.height += new_allocation.y;
10594               new_allocation.y = 0;
10595             }
10596           if (new_allocation.x + new_allocation.width > twidth)
10597             new_allocation.width = twidth - new_allocation.x;
10598           if (new_allocation.y + new_allocation.height > theight)
10599             new_allocation.height = theight - new_allocation.y;
10600
10601           gdk_window_get_position (window, &tx, &ty);
10602           new_allocation.x += tx;
10603           x_offset += tx;
10604           new_allocation.y += ty;
10605           y_offset += ty;
10606           
10607           window = gdk_window_get_parent (window);
10608         }
10609     }
10610
10611   if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
10612       (data->x < new_allocation.x + new_allocation.width) && 
10613       (data->y < new_allocation.y + new_allocation.height))
10614     {
10615       /* First, check if the drag is in a valid drop site in
10616        * one of our children 
10617        */
10618       if (GTK_IS_CONTAINER (widget))
10619         {
10620           FindWidgetData new_data = *data;
10621           
10622           new_data.x -= x_offset;
10623           new_data.y -= y_offset;
10624           new_data.found = FALSE;
10625           new_data.first = FALSE;
10626           
10627           gtk_container_forall (GTK_CONTAINER (widget),
10628                                 (GtkCallback)find_widget,
10629                                 &new_data);
10630           
10631           data->found = new_data.found;
10632           if (data->found)
10633             data->res_widget = new_data.res_widget;
10634         }
10635
10636       /* If not, and this widget is registered as a drop site, check to
10637        * emit "drag_motion" to check if we are actually in
10638        * a drop site.
10639        */
10640       if (!data->found)
10641         {
10642           data->found = TRUE;
10643           data->res_widget = widget;
10644         }
10645     }
10646 }
10647
10648 static GtkWidget *
10649 find_widget_at_pointer (GdkScreen *screen)
10650 {
10651   GtkWidget *widget = NULL;
10652   GdkWindow *pointer_window;
10653   gint x, y;
10654   FindWidgetData data;
10655  
10656  pointer_window = gdk_screen_get_window_at_pointer (screen, NULL, NULL);
10657  
10658  if (pointer_window)
10659    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);
10660
10661  if (widget)
10662    {
10663      gdk_window_get_pointer (widget->window,
10664                              &x, &y, NULL);
10665      
10666      data.x = x;
10667      data.y = y;
10668      data.found = FALSE;
10669      data.first = TRUE;
10670
10671      find_widget (widget, &data);
10672      if (data.found)
10673        return data.res_widget;
10674      return widget;
10675    }
10676  return NULL;
10677 }
10678
10679 struct PropertiesData {
10680   GtkWidget **window;
10681   GdkCursor *cursor;
10682   gboolean in_query;
10683   gint handler;
10684 };
10685
10686 static void
10687 destroy_properties (GtkWidget             *widget,
10688                     struct PropertiesData *data)
10689 {
10690   if (data->window)
10691     {
10692       *data->window = NULL;
10693       data->window = NULL;
10694     }
10695
10696   if (data->cursor)
10697     {
10698       gdk_cursor_destroy (data->cursor);
10699       data->cursor = NULL;
10700     }
10701
10702   if (data->handler)
10703     {
10704       gtk_signal_disconnect (widget, data->handler);
10705       data->handler = 0;
10706     }
10707
10708   g_free (data);
10709 }
10710
10711 static gint
10712 property_query_event (GtkWidget        *widget,
10713                       GdkEvent         *event,
10714                       struct PropertiesData *data)
10715 {
10716   GtkWidget *res_widget = NULL;
10717
10718   if (!data->in_query)
10719     return FALSE;
10720   
10721   if (event->type == GDK_BUTTON_RELEASE)
10722     {
10723       gtk_grab_remove (widget);
10724       gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
10725                                   GDK_CURRENT_TIME);
10726       
10727       res_widget = find_widget_at_pointer (gtk_widget_get_screen (widget));
10728       if (res_widget)
10729         {
10730           g_object_set_data (G_OBJECT (res_widget), "prop-editor-screen",
10731                              gtk_widget_get_screen (widget));
10732           create_prop_editor (G_OBJECT (res_widget), 0);
10733         }
10734
10735       data->in_query = FALSE;
10736     }
10737   return FALSE;
10738 }
10739
10740
10741 static void
10742 query_properties (GtkButton *button,
10743                   struct PropertiesData *data)
10744 {
10745   gint failure;
10746
10747   gtk_signal_connect (GTK_OBJECT (button), "event",
10748                       (GtkSignalFunc) property_query_event, data);
10749
10750
10751   if (!data->cursor)
10752     data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (button)),
10753                                                GDK_TARGET);
10754   
10755   failure = gdk_pointer_grab (GTK_WIDGET (button)->window,
10756                               TRUE,
10757                               GDK_BUTTON_RELEASE_MASK,
10758                               NULL,
10759                               data->cursor,
10760                               GDK_CURRENT_TIME);
10761
10762   gtk_grab_add (GTK_WIDGET (button));
10763
10764   data->in_query = TRUE;
10765 }
10766
10767 static void
10768 create_properties (GtkWidget *widget)
10769 {
10770   static GtkWidget *window = NULL;
10771   GtkWidget *button;
10772   GtkWidget *vbox;
10773   GtkWidget *label;
10774   struct PropertiesData *data;
10775
10776   data = g_new (struct PropertiesData, 1);
10777   data->window = &window;
10778   data->in_query = FALSE;
10779   data->cursor = NULL;
10780   data->handler = 0;
10781
10782   if (!window)
10783     {
10784       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10785
10786       gtk_window_set_screen (GTK_WINDOW (window),
10787                              gtk_widget_get_screen (widget));      
10788
10789       data->handler = gtk_signal_connect (GTK_OBJECT (window), "destroy",
10790                                           GTK_SIGNAL_FUNC(destroy_properties),
10791                                           data);
10792
10793       gtk_window_set_title (GTK_WINDOW (window), "test properties");
10794       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10795
10796       vbox = gtk_vbox_new (FALSE, 1);
10797       gtk_container_add (GTK_CONTAINER (window), vbox);
10798             
10799       label = gtk_label_new ("This is just a dumb test to test properties.\nIf you need a generic module, get GLE.");
10800       gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
10801       
10802       button = gtk_button_new_with_label ("Query properties");
10803       gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
10804       gtk_signal_connect (GTK_OBJECT (button), "clicked",
10805                           GTK_SIGNAL_FUNC(query_properties),
10806                           data);
10807     }
10808
10809   if (!GTK_WIDGET_VISIBLE (window))
10810     gtk_widget_show_all (window);
10811   else
10812     gtk_widget_destroy (window);
10813   
10814 }
10815
10816
10817 /*
10818  * Color Preview
10819  */
10820
10821 static int color_idle = 0;
10822
10823 gint
10824 color_idle_func (GtkWidget *preview)
10825 {
10826   static int count = 1;
10827   guchar buf[768];
10828   int i, j, k;
10829
10830   for (i = 0; i < 256; i++)
10831     {
10832       for (j = 0, k = 0; j < 256; j++)
10833         {
10834           buf[k+0] = i + count;
10835           buf[k+1] = 0;
10836           buf[k+2] = j + count;
10837           k += 3;
10838         }
10839
10840       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10841     }
10842
10843   count += 1;
10844
10845   gtk_widget_draw (preview, NULL);
10846
10847   return TRUE;
10848 }
10849
10850 static void
10851 color_preview_destroy (GtkWidget  *widget,
10852                        GtkWidget **window)
10853 {
10854   gtk_idle_remove (color_idle);
10855   color_idle = 0;
10856
10857   *window = NULL;
10858 }
10859
10860 void
10861 create_color_preview (GtkWidget *widget)
10862 {
10863   static GtkWidget *window = NULL;
10864   GtkWidget *preview;
10865   guchar buf[768];
10866   int i, j, k;
10867
10868   if (!window)
10869     {
10870       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10871       
10872       gtk_window_set_screen (GTK_WINDOW (window),
10873                              gtk_widget_get_screen (widget));
10874
10875       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10876                           GTK_SIGNAL_FUNC(color_preview_destroy),
10877                           &window);
10878
10879       gtk_window_set_title (GTK_WINDOW (window), "test");
10880       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10881
10882       preview = gtk_preview_new (GTK_PREVIEW_COLOR);
10883       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10884       gtk_container_add (GTK_CONTAINER (window), preview);
10885
10886       for (i = 0; i < 256; i++)
10887         {
10888           for (j = 0, k = 0; j < 256; j++)
10889             {
10890               buf[k+0] = i;
10891               buf[k+1] = 0;
10892               buf[k+2] = j;
10893               k += 3;
10894             }
10895
10896           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10897         }
10898
10899       color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
10900     }
10901
10902   if (!GTK_WIDGET_VISIBLE (window))
10903     gtk_widget_show_all (window);
10904   else
10905     gtk_widget_destroy (window);
10906 }
10907
10908 /*
10909  * Gray Preview
10910  */
10911
10912 static int gray_idle = 0;
10913
10914 gint
10915 gray_idle_func (GtkWidget *preview)
10916 {
10917   static int count = 1;
10918   guchar buf[256];
10919   int i, j;
10920
10921   for (i = 0; i < 256; i++)
10922     {
10923       for (j = 0; j < 256; j++)
10924         buf[j] = i + j + count;
10925
10926       gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10927     }
10928
10929   count += 1;
10930
10931   gtk_widget_draw (preview, NULL);
10932
10933   return TRUE;
10934 }
10935
10936 static void
10937 gray_preview_destroy (GtkWidget  *widget,
10938                       GtkWidget **window)
10939 {
10940   gtk_idle_remove (gray_idle);
10941   gray_idle = 0;
10942
10943   *window = NULL;
10944 }
10945
10946 void
10947 create_gray_preview (GtkWidget *widget)
10948 {
10949   static GtkWidget *window = NULL;
10950   GtkWidget *preview;
10951   guchar buf[256];
10952   int i, j;
10953
10954   if (!window)
10955     {
10956       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
10957
10958       gtk_window_set_screen (GTK_WINDOW (window),
10959                              gtk_widget_get_screen (widget));
10960
10961       gtk_signal_connect (GTK_OBJECT (window), "destroy",
10962                           GTK_SIGNAL_FUNC(gray_preview_destroy),
10963                           &window);
10964
10965       gtk_window_set_title (GTK_WINDOW (window), "test");
10966       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
10967
10968       preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
10969       gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
10970       gtk_container_add (GTK_CONTAINER (window), preview);
10971
10972       for (i = 0; i < 256; i++)
10973         {
10974           for (j = 0; j < 256; j++)
10975             buf[j] = i + j;
10976
10977           gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
10978         }
10979
10980       gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
10981     }
10982
10983   if (!GTK_WIDGET_VISIBLE (window))
10984     gtk_widget_show_all (window);
10985   else
10986     gtk_widget_destroy (window);
10987 }
10988
10989
10990 /*
10991  * Selection Test
10992  */
10993
10994 void
10995 selection_test_received (GtkWidget *list, GtkSelectionData *data)
10996 {
10997   GdkAtom *atoms;
10998   GtkWidget *list_item;
10999   GList *item_list;
11000   int i, l;
11001
11002   if (data->length < 0)
11003     {
11004       g_print ("Selection retrieval failed\n");
11005       return;
11006     }
11007   if (data->type != GDK_SELECTION_TYPE_ATOM)
11008     {
11009       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
11010       return;
11011     }
11012
11013   /* Clear out any current list items */
11014
11015   gtk_list_clear_items (GTK_LIST(list), 0, -1);
11016
11017   /* Add new items to list */
11018
11019   atoms = (GdkAtom *)data->data;
11020
11021   item_list = NULL;
11022   l = data->length / sizeof (GdkAtom);
11023   for (i = 0; i < l; i++)
11024     {
11025       char *name;
11026       name = gdk_atom_name (atoms[i]);
11027       if (name != NULL)
11028         {
11029           list_item = gtk_list_item_new_with_label (name);
11030           g_free (name);
11031         }
11032       else
11033         list_item = gtk_list_item_new_with_label ("(bad atom)");
11034
11035       gtk_widget_show (list_item);
11036       item_list = g_list_append (item_list, list_item);
11037     }
11038
11039   gtk_list_append_items (GTK_LIST (list), item_list);
11040
11041   return;
11042 }
11043
11044 void
11045 selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
11046 {
11047   static GdkAtom targets_atom = GDK_NONE;
11048
11049   if (targets_atom == GDK_NONE)
11050     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
11051
11052   gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
11053                          GDK_CURRENT_TIME);
11054 }
11055
11056 void
11057 create_selection_test (GtkWidget *widget)
11058 {
11059   static GtkWidget *window = NULL;
11060   GtkWidget *button;
11061   GtkWidget *vbox;
11062   GtkWidget *scrolled_win;
11063   GtkWidget *list;
11064   GtkWidget *label;
11065
11066   if (!window)
11067     {
11068       window = gtk_dialog_new ();
11069       
11070       gtk_window_set_screen (GTK_WINDOW (window),
11071                              gtk_widget_get_screen (widget));
11072
11073       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11074                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11075                           &window);
11076
11077       gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
11078       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11079
11080       /* Create the list */
11081
11082       vbox = gtk_vbox_new (FALSE, 5);
11083       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11084       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
11085                           TRUE, TRUE, 0);
11086
11087       label = gtk_label_new ("Gets available targets for current selection");
11088       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11089
11090       scrolled_win = gtk_scrolled_window_new (NULL, NULL);
11091       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
11092                                       GTK_POLICY_AUTOMATIC, 
11093                                       GTK_POLICY_AUTOMATIC);
11094       gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
11095       gtk_widget_set_usize (scrolled_win, 100, 200);
11096
11097       list = gtk_list_new ();
11098       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win), list);
11099
11100       gtk_signal_connect (GTK_OBJECT(list), "selection_received",
11101                           GTK_SIGNAL_FUNC (selection_test_received), NULL);
11102
11103       /* .. And create some buttons */
11104       button = gtk_button_new_with_label ("Get Targets");
11105       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11106                           button, TRUE, TRUE, 0);
11107
11108       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11109                           GTK_SIGNAL_FUNC (selection_test_get_targets), list);
11110
11111       button = gtk_button_new_with_label ("Quit");
11112       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11113                           button, TRUE, TRUE, 0);
11114
11115       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11116                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11117                                  GTK_OBJECT (window));
11118     }
11119
11120   if (!GTK_WIDGET_VISIBLE (window))
11121     gtk_widget_show_all (window);
11122   else
11123     gtk_widget_destroy (window);
11124 }
11125
11126 /*
11127  * Gamma Curve
11128  */
11129
11130 void
11131 create_gamma_curve (GtkWidget *widget)
11132 {
11133   static GtkWidget *window = NULL, *curve;
11134   static int count = 0;
11135   gfloat vec[256];
11136   gint max;
11137   gint i;
11138   
11139   if (!window)
11140     {
11141       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11142       gtk_window_set_screen (GTK_WINDOW (window),
11143                              gtk_widget_get_screen (widget));
11144
11145       gtk_window_set_title (GTK_WINDOW (window), "test");
11146       gtk_container_set_border_width (GTK_CONTAINER (window), 10);
11147
11148       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11149                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11150                           &window);
11151
11152       curve = gtk_gamma_curve_new ();
11153       gtk_container_add (GTK_CONTAINER (window), curve);
11154       gtk_widget_show (curve);
11155     }
11156
11157   max = 127 + (count % 2)*128;
11158   gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11159                        0, max, 0, max);
11160   for (i = 0; i < max; ++i)
11161     vec[i] = (127 / sqrt (max)) * sqrt (i);
11162   gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
11163                         max, vec);
11164
11165   if (!GTK_WIDGET_VISIBLE (window))
11166     gtk_widget_show (window);
11167   else if (count % 4 == 3)
11168     {
11169       gtk_widget_destroy (window);
11170       window = NULL;
11171     }
11172
11173   ++count;
11174 }
11175
11176 /*
11177  * Test scrolling
11178  */
11179
11180 static int scroll_test_pos = 0.0;
11181
11182 static gint
11183 scroll_test_expose (GtkWidget *widget, GdkEventExpose *event,
11184                     GtkAdjustment *adj)
11185 {
11186   gint i,j;
11187   gint imin, imax, jmin, jmax;
11188   
11189   imin = (event->area.x) / 10;
11190   imax = (event->area.x + event->area.width + 9) / 10;
11191
11192   jmin = ((int)adj->value + event->area.y) / 10;
11193   jmax = ((int)adj->value + event->area.y + event->area.height + 9) / 10;
11194
11195   gdk_window_clear_area (widget->window,
11196                          event->area.x, event->area.y,
11197                          event->area.width, event->area.height);
11198
11199   for (i=imin; i<imax; i++)
11200     for (j=jmin; j<jmax; j++)
11201       if ((i+j) % 2)
11202         gdk_draw_rectangle (widget->window, 
11203                             widget->style->black_gc,
11204                             TRUE,
11205                             10*i, 10*j - (int)adj->value, 1+i%10, 1+j%10);
11206
11207   return TRUE;
11208 }
11209
11210 static gint
11211 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
11212                     GtkAdjustment *adj)
11213 {
11214   gdouble new_value = adj->value + ((event->direction == GDK_SCROLL_UP) ?
11215                                     -adj->page_increment / 2:
11216                                     adj->page_increment / 2);
11217   new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
11218   gtk_adjustment_set_value (adj, new_value);  
11219   
11220   return TRUE;
11221 }
11222
11223 static void
11224 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
11225                        GtkAdjustment *adj)
11226 {
11227   adj->page_increment = 0.9 * widget->allocation.height;
11228   adj->page_size = widget->allocation.height;
11229
11230   gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
11231 }
11232
11233 static void
11234 scroll_test_adjustment_changed (GtkAdjustment *adj, GtkWidget *widget)
11235 {
11236   /* gint source_min = (int)adj->value - scroll_test_pos; */
11237   gint dy;
11238
11239   dy = scroll_test_pos - (int)adj->value;
11240   scroll_test_pos = adj->value;
11241
11242   if (!GTK_WIDGET_DRAWABLE (widget))
11243     return;
11244   gdk_window_scroll (widget->window, 0, dy);
11245   gdk_window_process_updates (widget->window, FALSE);
11246 }
11247
11248
11249 void
11250 create_scroll_test (GtkWidget *widget)
11251 {
11252   static GtkWidget *window = NULL;
11253   GtkWidget *hbox;
11254   GtkWidget *drawing_area;
11255   GtkWidget *scrollbar;
11256   GtkWidget *button;
11257   GtkAdjustment *adj;
11258   GdkGeometry geometry;
11259   GdkWindowHints geometry_mask;
11260
11261   if (!window)
11262     {
11263       window = gtk_dialog_new ();
11264
11265       gtk_window_set_screen (GTK_WINDOW (window),
11266                              gtk_widget_get_screen (widget));
11267
11268       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11269                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11270                           &window);
11271
11272       gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
11273       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11274
11275       hbox = gtk_hbox_new (FALSE, 0);
11276       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
11277                           TRUE, TRUE, 0);
11278       gtk_widget_show (hbox);
11279
11280       drawing_area = gtk_drawing_area_new ();
11281       gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
11282       gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
11283       gtk_widget_show (drawing_area);
11284
11285       gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
11286
11287       adj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0));
11288       scroll_test_pos = 0.0;
11289
11290       scrollbar = gtk_vscrollbar_new (adj);
11291       gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
11292       gtk_widget_show (scrollbar);
11293
11294       gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
11295                           GTK_SIGNAL_FUNC (scroll_test_expose), adj);
11296       gtk_signal_connect (GTK_OBJECT (drawing_area), "configure_event",
11297                           GTK_SIGNAL_FUNC (scroll_test_configure), adj);
11298       gtk_signal_connect (GTK_OBJECT (drawing_area), "scroll_event",
11299                           GTK_SIGNAL_FUNC (scroll_test_scroll), adj);
11300       
11301       gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
11302                           GTK_SIGNAL_FUNC (scroll_test_adjustment_changed),
11303                           drawing_area);
11304       
11305       /* .. And create some buttons */
11306
11307       button = gtk_button_new_with_label ("Quit");
11308       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
11309                           button, TRUE, TRUE, 0);
11310
11311       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11312                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11313                                  GTK_OBJECT (window));
11314       gtk_widget_show (button);
11315
11316       /* Set up gridded geometry */
11317
11318       geometry_mask = GDK_HINT_MIN_SIZE | 
11319                        GDK_HINT_BASE_SIZE | 
11320                        GDK_HINT_RESIZE_INC;
11321
11322       geometry.min_width = 20;
11323       geometry.min_height = 20;
11324       geometry.base_width = 0;
11325       geometry.base_height = 0;
11326       geometry.width_inc = 10;
11327       geometry.height_inc = 10;
11328       
11329       gtk_window_set_geometry_hints (GTK_WINDOW (window),
11330                                drawing_area, &geometry, geometry_mask);
11331     }
11332
11333   if (!GTK_WIDGET_VISIBLE (window))
11334     gtk_widget_show (window);
11335   else
11336     gtk_widget_destroy (window);
11337 }
11338
11339 /*
11340  * Timeout Test
11341  */
11342
11343 static int timer = 0;
11344
11345 gint
11346 timeout_test (GtkWidget *label)
11347 {
11348   static int count = 0;
11349   static char buffer[32];
11350
11351   sprintf (buffer, "count: %d", ++count);
11352   gtk_label_set_text (GTK_LABEL (label), buffer);
11353
11354   return TRUE;
11355 }
11356
11357 void
11358 start_timeout_test (GtkWidget *widget,
11359                     GtkWidget *label)
11360 {
11361   if (!timer)
11362     {
11363       timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
11364     }
11365 }
11366
11367 void
11368 stop_timeout_test (GtkWidget *widget,
11369                    gpointer   data)
11370 {
11371   if (timer)
11372     {
11373       gtk_timeout_remove (timer);
11374       timer = 0;
11375     }
11376 }
11377
11378 void
11379 destroy_timeout_test (GtkWidget  *widget,
11380                       GtkWidget **window)
11381 {
11382   stop_timeout_test (NULL, NULL);
11383
11384   *window = NULL;
11385 }
11386
11387 void
11388 create_timeout_test (GtkWidget *widget)
11389 {
11390   static GtkWidget *window = NULL;
11391   GtkWidget *button;
11392   GtkWidget *label;
11393
11394   if (!window)
11395     {
11396       window = gtk_dialog_new ();
11397
11398       gtk_window_set_screen (GTK_WINDOW (window),
11399                              gtk_widget_get_screen (widget));
11400
11401       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11402                           GTK_SIGNAL_FUNC(destroy_timeout_test),
11403                           &window);
11404
11405       gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
11406       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11407
11408       label = gtk_label_new ("count: 0");
11409       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11410       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11411                           label, TRUE, TRUE, 0);
11412       gtk_widget_show (label);
11413
11414       button = gtk_button_new_with_label ("close");
11415       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11416                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11417                                  GTK_OBJECT (window));
11418       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11419       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11420                           button, TRUE, TRUE, 0);
11421       gtk_widget_grab_default (button);
11422       gtk_widget_show (button);
11423
11424       button = gtk_button_new_with_label ("start");
11425       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11426                           GTK_SIGNAL_FUNC(start_timeout_test),
11427                           label);
11428       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11429       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11430                           button, TRUE, TRUE, 0);
11431       gtk_widget_show (button);
11432
11433       button = gtk_button_new_with_label ("stop");
11434       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11435                           GTK_SIGNAL_FUNC(stop_timeout_test),
11436                           NULL);
11437       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11438       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11439                           button, TRUE, TRUE, 0);
11440       gtk_widget_show (button);
11441     }
11442
11443   if (!GTK_WIDGET_VISIBLE (window))
11444     gtk_widget_show (window);
11445   else
11446     gtk_widget_destroy (window);
11447 }
11448
11449 /*
11450  * Idle Test
11451  */
11452
11453 static int idle_id = 0;
11454
11455 static gint
11456 idle_test (GtkWidget *label)
11457 {
11458   static int count = 0;
11459   static char buffer[32];
11460
11461   sprintf (buffer, "count: %d", ++count);
11462   gtk_label_set_text (GTK_LABEL (label), buffer);
11463
11464   return TRUE;
11465 }
11466
11467 static void
11468 start_idle_test (GtkWidget *widget,
11469                  GtkWidget *label)
11470 {
11471   if (!idle_id)
11472     {
11473       idle_id = gtk_idle_add ((GtkFunction) idle_test, label);
11474     }
11475 }
11476
11477 static void
11478 stop_idle_test (GtkWidget *widget,
11479                 gpointer   data)
11480 {
11481   if (idle_id)
11482     {
11483       gtk_idle_remove (idle_id);
11484       idle_id = 0;
11485     }
11486 }
11487
11488 static void
11489 destroy_idle_test (GtkWidget  *widget,
11490                    GtkWidget **window)
11491 {
11492   stop_idle_test (NULL, NULL);
11493
11494   *window = NULL;
11495 }
11496
11497 static void
11498 toggle_idle_container (GtkObject *button,
11499                        GtkContainer *container)
11500 {
11501   gtk_container_set_resize_mode (container, GPOINTER_TO_INT (gtk_object_get_user_data (button)));
11502 }
11503
11504 static void
11505 create_idle_test (GtkWidget *widget)
11506 {
11507   static GtkWidget *window = NULL;
11508   GtkWidget *button;
11509   GtkWidget *label;
11510   GtkWidget *container;
11511
11512   if (!window)
11513     {
11514       GtkWidget *button2;
11515       GtkWidget *frame;
11516       GtkWidget *box;
11517
11518       window = gtk_dialog_new ();
11519
11520       gtk_window_set_screen (GTK_WINDOW (window),
11521                              gtk_widget_get_screen (widget));
11522
11523       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11524                           GTK_SIGNAL_FUNC(destroy_idle_test),
11525                           &window);
11526
11527       gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
11528       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11529
11530       label = gtk_label_new ("count: 0");
11531       gtk_misc_set_padding (GTK_MISC (label), 10, 10);
11532       gtk_widget_show (label);
11533       
11534       container =
11535         gtk_widget_new (GTK_TYPE_HBOX,
11536                         "visible", TRUE,
11537                         /* "GtkContainer::child", gtk_widget_new (GTK_TYPE_HBOX,
11538                          * "GtkWidget::visible", TRUE,
11539                          */
11540                          "child", label,
11541                         /* NULL), */
11542                         NULL);
11543       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
11544                           container, TRUE, TRUE, 0);
11545
11546       frame =
11547         gtk_widget_new (GTK_TYPE_FRAME,
11548                         "border_width", 5,
11549                         "label", "Label Container",
11550                         "visible", TRUE,
11551                         "parent", GTK_DIALOG (window)->vbox,
11552                         NULL);
11553       box =
11554         gtk_widget_new (GTK_TYPE_VBOX,
11555                         "visible", TRUE,
11556                         "parent", frame,
11557                         NULL);
11558       button =
11559         g_object_connect (gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11560                                           "label", "Resize-Parent",
11561                                           "user_data", (void*)GTK_RESIZE_PARENT,
11562                                           "visible", TRUE,
11563                                           "parent", box,
11564                                           NULL),
11565                           "signal::clicked", toggle_idle_container, container,
11566                           NULL);
11567       button = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11568                                "label", "Resize-Queue",
11569                                "user_data", (void*)GTK_RESIZE_QUEUE,
11570                                "group", button,
11571                                "visible", TRUE,
11572                                "parent", box,
11573                                NULL);
11574       g_object_connect (button,
11575                         "signal::clicked", toggle_idle_container, container,
11576                         NULL);
11577       button2 = gtk_widget_new (GTK_TYPE_RADIO_BUTTON,
11578                                 "label", "Resize-Immediate",
11579                                 "user_data", (void*)GTK_RESIZE_IMMEDIATE,
11580                                 NULL);
11581       g_object_connect (button2,
11582                         "signal::clicked", toggle_idle_container, container,
11583                         NULL);
11584       g_object_set (button2,
11585                     "group", button,
11586                     "visible", TRUE,
11587                     "parent", box,
11588                     NULL);
11589
11590       button = gtk_button_new_with_label ("close");
11591       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11592                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11593                                  GTK_OBJECT (window));
11594       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11595       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11596                           button, TRUE, TRUE, 0);
11597       gtk_widget_grab_default (button);
11598       gtk_widget_show (button);
11599
11600       button = gtk_button_new_with_label ("start");
11601       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11602                           GTK_SIGNAL_FUNC(start_idle_test),
11603                           label);
11604       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11605       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11606                           button, TRUE, TRUE, 0);
11607       gtk_widget_show (button);
11608
11609       button = gtk_button_new_with_label ("stop");
11610       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11611                           GTK_SIGNAL_FUNC(stop_idle_test),
11612                           NULL);
11613       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11614       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11615                           button, TRUE, TRUE, 0);
11616       gtk_widget_show (button);
11617     }
11618
11619   if (!GTK_WIDGET_VISIBLE (window))
11620     gtk_widget_show (window);
11621   else
11622     gtk_widget_destroy (window);
11623 }
11624
11625 /*
11626  * rc file test
11627  */
11628
11629 void
11630 reload_all_rc_files (void)
11631 {
11632   static GdkAtom atom_rcfiles = GDK_NONE;
11633
11634   GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
11635   int i;
11636   
11637   if (!atom_rcfiles)
11638     atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
11639
11640   for(i = 0; i < 5; i++)
11641     send_event->client.data.l[i] = 0;
11642   send_event->client.data_format = 32;
11643   send_event->client.message_type = atom_rcfiles;
11644   gdk_event_send_clientmessage_toall (send_event);
11645
11646   gdk_event_free (send_event);
11647 }
11648
11649 void
11650 create_rc_file (GtkWidget *widget)
11651 {
11652   static GtkWidget *window = NULL;
11653   GtkWidget *button;
11654   GtkWidget *frame;
11655   GtkWidget *vbox;
11656   GtkWidget *label;
11657
11658   if (!window)
11659     {
11660       window = gtk_dialog_new ();
11661
11662       gtk_window_set_screen (GTK_WINDOW (window),
11663                              gtk_widget_get_screen (widget));
11664
11665       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11666                           GTK_SIGNAL_FUNC(destroy_idle_test),
11667                           &window);
11668
11669       frame = gtk_aspect_frame_new ("Testing RC file prioritization", 0.5, 0.5, 0.0, TRUE);
11670       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), frame, FALSE, FALSE, 0);
11671
11672       vbox = gtk_vbox_new (FALSE, 0);
11673       gtk_container_add (GTK_CONTAINER (frame), vbox);
11674       
11675       label = gtk_label_new ("This label should be red");
11676       gtk_widget_set_name (label, "testgtk-red-label");
11677       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11678
11679       label = gtk_label_new ("This label should be green");
11680       gtk_widget_set_name (label, "testgtk-green-label");
11681       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11682
11683       label = gtk_label_new ("This label should be blue");
11684       gtk_widget_set_name (label, "testgtk-blue-label");
11685       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11686
11687       gtk_window_set_title (GTK_WINDOW (window), "Reload Rc file");
11688       gtk_container_set_border_width (GTK_CONTAINER (window), 0);
11689
11690       button = gtk_button_new_with_label ("Reload");
11691       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11692                           GTK_SIGNAL_FUNC(gtk_rc_reparse_all), NULL);
11693       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11694       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11695                           button, TRUE, TRUE, 0);
11696       gtk_widget_grab_default (button);
11697
11698       button = gtk_button_new_with_label ("Reload All");
11699       gtk_signal_connect (GTK_OBJECT (button), "clicked",
11700                           GTK_SIGNAL_FUNC(reload_all_rc_files), NULL);
11701       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11702       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11703                           button, TRUE, TRUE, 0);
11704
11705       button = gtk_button_new_with_label ("Close");
11706       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11707                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11708                                  GTK_OBJECT (window));
11709       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11710       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11711                           button, TRUE, TRUE, 0);
11712     }
11713
11714   if (!GTK_WIDGET_VISIBLE (window))
11715     gtk_widget_show_all (window);
11716   else
11717     gtk_widget_destroy (window);
11718 }
11719
11720 /*
11721  * Test of recursive mainloop
11722  */
11723
11724 void
11725 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
11726 {
11727   *window = NULL;
11728   gtk_main_quit ();
11729 }
11730
11731 void
11732 create_mainloop (GtkWidget *widget)
11733 {
11734   static GtkWidget *window = NULL;
11735   GtkWidget *label;
11736   GtkWidget *button;
11737
11738   if (!window)
11739     {
11740       window = gtk_dialog_new ();
11741
11742       gtk_window_set_screen (GTK_WINDOW (window),
11743                              gtk_widget_get_screen (widget));
11744
11745       gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
11746
11747       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11748                           GTK_SIGNAL_FUNC(mainloop_destroyed),
11749                           &window);
11750
11751       label = gtk_label_new ("In recursive main loop...");
11752       gtk_misc_set_padding (GTK_MISC(label), 20, 20);
11753
11754       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label,
11755                           TRUE, TRUE, 0);
11756       gtk_widget_show (label);
11757
11758       button = gtk_button_new_with_label ("Leave");
11759       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, 
11760                           FALSE, TRUE, 0);
11761
11762       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11763                                  GTK_SIGNAL_FUNC (gtk_widget_destroy),
11764                                  GTK_OBJECT (window));
11765
11766       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11767       gtk_widget_grab_default (button);
11768
11769       gtk_widget_show (button);
11770     }
11771
11772   if (!GTK_WIDGET_VISIBLE (window))
11773     {
11774       gtk_widget_show (window);
11775
11776       g_print ("create_mainloop: start\n");
11777       gtk_main ();
11778       g_print ("create_mainloop: done\n");
11779     }
11780   else
11781     gtk_widget_destroy (window);
11782 }
11783
11784 gboolean
11785 layout_expose_handler (GtkWidget *widget, GdkEventExpose *event)
11786 {
11787   GtkLayout *layout;
11788
11789   gint i,j;
11790   gint imin, imax, jmin, jmax;
11791
11792   layout = GTK_LAYOUT (widget);
11793
11794   if (event->window != layout->bin_window)
11795     return FALSE;
11796   
11797   imin = (event->area.x) / 10;
11798   imax = (event->area.x + event->area.width + 9) / 10;
11799
11800   jmin = (event->area.y) / 10;
11801   jmax = (event->area.y + event->area.height + 9) / 10;
11802
11803   for (i=imin; i<imax; i++)
11804     for (j=jmin; j<jmax; j++)
11805       if ((i+j) % 2)
11806         gdk_draw_rectangle (layout->bin_window,
11807                             widget->style->black_gc,
11808                             TRUE,
11809                             10*i, 10*j, 
11810                             1+i%10, 1+j%10);
11811   
11812   return FALSE;
11813 }
11814
11815 void create_layout (GtkWidget *widget)
11816 {
11817   static GtkWidget *window = NULL;
11818   GtkWidget *layout;
11819   GtkWidget *scrolledwindow;
11820   GtkWidget *button;
11821
11822   if (!window)
11823     {
11824       gchar buf[16];
11825
11826       gint i, j;
11827       
11828       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
11829       gtk_window_set_screen (GTK_WINDOW (window),
11830                              gtk_widget_get_screen (widget));
11831
11832       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11833                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11834                           &window);
11835
11836       gtk_window_set_title (GTK_WINDOW (window), "Layout");
11837       gtk_widget_set_usize (window, 200, 200);
11838
11839       scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
11840       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
11841                                            GTK_SHADOW_IN);
11842       gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
11843                                          GTK_CORNER_TOP_RIGHT);
11844
11845       gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
11846       
11847       layout = gtk_layout_new (NULL, NULL);
11848       gtk_container_add (GTK_CONTAINER (scrolledwindow), layout);
11849
11850       /* We set step sizes here since GtkLayout does not set
11851        * them itself.
11852        */
11853       GTK_LAYOUT (layout)->hadjustment->step_increment = 10.0;
11854       GTK_LAYOUT (layout)->vadjustment->step_increment = 10.0;
11855       
11856       gtk_widget_set_events (layout, GDK_EXPOSURE_MASK);
11857       gtk_signal_connect (GTK_OBJECT (layout), "expose_event",
11858                           GTK_SIGNAL_FUNC (layout_expose_handler), NULL);
11859       
11860       gtk_layout_set_size (GTK_LAYOUT (layout), 1600, 128000);
11861       
11862       for (i=0 ; i < 16 ; i++)
11863         for (j=0 ; j < 16 ; j++)
11864           {
11865             sprintf(buf, "Button %d, %d", i, j);
11866             if ((i + j) % 2)
11867               button = gtk_button_new_with_label (buf);
11868             else
11869               button = gtk_label_new (buf);
11870
11871             gtk_layout_put (GTK_LAYOUT (layout), button,
11872                             j*100, i*100);
11873           }
11874
11875       for (i=16; i < 1280; i++)
11876         {
11877           sprintf(buf, "Button %d, %d", i, 0);
11878           if (i % 2)
11879             button = gtk_button_new_with_label (buf);
11880           else
11881             button = gtk_label_new (buf);
11882
11883           gtk_layout_put (GTK_LAYOUT (layout), button,
11884                           0, i*100);
11885         }
11886     }
11887
11888   if (!GTK_WIDGET_VISIBLE (window))
11889     gtk_widget_show_all (window);
11890   else
11891     gtk_widget_destroy (window);
11892 }
11893
11894 void
11895 create_styles (GtkWidget *widget)
11896 {
11897   static GtkWidget *window = NULL;
11898   GtkWidget *label;
11899   GtkWidget *button;
11900   GtkWidget *entry;
11901   GtkWidget *vbox;
11902   static GdkColor red =    { 0, 0xffff, 0,      0      };
11903   static GdkColor green =  { 0, 0,      0xffff, 0      };
11904   static GdkColor blue =   { 0, 0,      0,      0xffff };
11905   static GdkColor yellow = { 0, 0xffff, 0xffff, 0      };
11906   static GdkColor cyan =   { 0, 0     , 0xffff, 0xffff };
11907   PangoFontDescription *font_desc;
11908
11909   GtkRcStyle *rc_style;
11910
11911   if (!window)
11912     {
11913       window = gtk_dialog_new ();
11914       gtk_window_set_screen (GTK_WINDOW (window),
11915                              gtk_widget_get_screen (widget));
11916      
11917       gtk_signal_connect (GTK_OBJECT (window), "destroy",
11918                           GTK_SIGNAL_FUNC(gtk_widget_destroyed),
11919                           &window);
11920
11921       
11922       button = gtk_button_new_with_label ("Close");
11923       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
11924                                  GTK_SIGNAL_FUNC(gtk_widget_destroy),
11925                                  GTK_OBJECT (window));
11926       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11927       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
11928                           button, TRUE, TRUE, 0);
11929       gtk_widget_show (button);
11930
11931       vbox = gtk_vbox_new (FALSE, 5);
11932       gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
11933       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, FALSE, FALSE, 0);
11934       
11935       label = gtk_label_new ("Font:");
11936       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11937       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11938
11939       font_desc = pango_font_description_from_string ("Helvetica,Sans Oblique 18");
11940
11941       button = gtk_button_new_with_label ("Some Text");
11942       gtk_widget_modify_font (GTK_BIN (button)->child, font_desc);
11943       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11944
11945       label = gtk_label_new ("Foreground:");
11946       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11947       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11948
11949       button = gtk_button_new_with_label ("Some Text");
11950       gtk_widget_modify_fg (GTK_BIN (button)->child, GTK_STATE_NORMAL, &red);
11951       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11952
11953       label = gtk_label_new ("Background:");
11954       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11955       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11956
11957       button = gtk_button_new_with_label ("Some Text");
11958       gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &green);
11959       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
11960
11961       label = gtk_label_new ("Text:");
11962       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11963       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11964
11965       entry = gtk_entry_new ();
11966       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11967       gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &blue);
11968       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11969
11970       label = gtk_label_new ("Base:");
11971       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11972       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11973
11974       entry = gtk_entry_new ();
11975       gtk_entry_set_text (GTK_ENTRY (entry), "Some Text");
11976       gtk_widget_modify_base (entry, GTK_STATE_NORMAL, &yellow);
11977       gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
11978
11979       label = gtk_label_new ("Multiple:");
11980       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
11981       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
11982
11983       button = gtk_button_new_with_label ("Some Text");
11984
11985       rc_style = gtk_rc_style_new ();
11986
11987       rc_style->font_desc = pango_font_description_copy (font_desc);
11988       rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
11989       rc_style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG | GTK_RC_BG;
11990       rc_style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG | GTK_RC_BG;
11991       rc_style->fg[GTK_STATE_NORMAL] = yellow;
11992       rc_style->bg[GTK_STATE_NORMAL] = blue;
11993       rc_style->fg[GTK_STATE_PRELIGHT] = blue;
11994       rc_style->bg[GTK_STATE_PRELIGHT] = yellow;
11995       rc_style->fg[GTK_STATE_ACTIVE] = red;
11996       rc_style->bg[GTK_STATE_ACTIVE] = cyan;
11997       rc_style->xthickness = 5;
11998       rc_style->ythickness = 5;
11999
12000       gtk_widget_modify_style (button, rc_style);
12001       gtk_widget_modify_style (GTK_BIN (button)->child, rc_style);
12002
12003       g_object_unref (G_OBJECT (rc_style));
12004       
12005       gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
12006     }
12007   
12008   if (!GTK_WIDGET_VISIBLE (window))
12009     gtk_widget_show_all (window);
12010   else
12011     gtk_widget_destroy (window);
12012 }
12013
12014 /*
12015  * Main Window and Exit
12016  */
12017
12018 void
12019 do_exit (GtkWidget *widget, GtkWidget *window)
12020 {
12021   gtk_widget_destroy (window);
12022   gtk_main_quit ();
12023 }
12024
12025 struct {
12026   char *label;
12027   void (*func) ();
12028   gboolean do_not_benchmark;
12029 } buttons[] =
12030 {
12031   { "big windows", create_big_windows },
12032   { "button box", create_button_box },
12033   { "buttons", create_buttons },
12034   { "check buttons", create_check_buttons },
12035   { "clist", create_clist},
12036   { "color selection", create_color_selection },
12037   { "ctree", create_ctree },
12038   { "cursors", create_cursors },
12039   { "dialog", create_dialog },
12040   { "display & screen", create_display_screen },
12041   { "entry", create_entry },
12042   { "event watcher", create_event_watcher },
12043   { "file selection", create_file_selection },
12044   { "flipping", create_flipping },
12045   { "focus", create_focus },
12046   { "font selection", create_font_selection },
12047   { "gamma curve", create_gamma_curve, TRUE },
12048   { "gridded geometry", create_gridded_geometry, TRUE },
12049   { "handle box", create_handle_box },
12050   { "image from drawable", create_get_image },
12051   { "image", create_image },
12052   { "item factory", create_item_factory },
12053   { "key lookup", create_key_lookup },
12054   { "labels", create_labels },
12055   { "layout", create_layout },
12056   { "list", create_list },
12057   { "menus", create_menus },
12058   { "message dialog", create_message_dialog },
12059   { "modal window", create_modal_window, TRUE },
12060   { "notebook", create_notebook },
12061   { "panes", create_panes },
12062   { "paned keyboard", create_paned_keyboard_navigation },
12063   { "pixmap", create_pixmap },
12064   { "preview color", create_color_preview, TRUE },
12065   { "preview gray", create_gray_preview, TRUE },
12066   { "progress bar", create_progress_bar },
12067   { "properties", create_properties },
12068   { "radio buttons", create_radio_buttons },
12069   { "range controls", create_range_controls },
12070   { "rc file", create_rc_file },
12071   { "reparent", create_reparent },
12072   { "rulers", create_rulers },
12073   { "saved position", create_saved_position },
12074   { "scrolled windows", create_scrolled_windows },
12075   { "shapes", create_shapes },
12076   { "size groups", create_size_groups },
12077   { "spinbutton", create_spins },
12078   { "statusbar", create_statusbar },
12079   { "styles", create_styles },
12080   { "test idle", create_idle_test },
12081   { "test mainloop", create_mainloop, TRUE },
12082   { "test scrolling", create_scroll_test },
12083   { "test selection", create_selection_test },
12084   { "test timeout", create_timeout_test },
12085   { "text", create_text },
12086   { "toggle buttons", create_toggle_buttons },
12087   { "toolbar", create_toolbar },
12088   { "tooltips", create_tooltips },
12089   { "tree", create_tree_mode_window},
12090   { "WM hints", create_wmhints },
12091   { "window sizing", create_window_sizing },
12092   { "window states", create_window_states }
12093 };
12094 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
12095
12096 void
12097 create_main_window (void)
12098 {
12099   GtkWidget *window;
12100   GtkWidget *box1;
12101   GtkWidget *box2;
12102   GtkWidget *scrolled_window;
12103   GtkWidget *button;
12104   GtkWidget *label;
12105   gchar buffer[64];
12106   GtkWidget *separator;
12107   GdkGeometry geometry;
12108   int i;
12109
12110   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
12111   gtk_widget_set_name (window, "main window");
12112   gtk_widget_set_uposition (window, 20, 20);
12113   gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
12114
12115   geometry.min_width = -1;
12116   geometry.min_height = -1;
12117   geometry.max_width = -1;
12118   geometry.max_height = G_MAXSHORT;
12119   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
12120                                  &geometry,
12121                                  GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
12122
12123   gtk_signal_connect (GTK_OBJECT (window), "destroy",
12124                       GTK_SIGNAL_FUNC(gtk_main_quit),
12125                       NULL);
12126   gtk_signal_connect (GTK_OBJECT (window), "delete-event",
12127                       GTK_SIGNAL_FUNC (gtk_false),
12128                       NULL);
12129
12130   box1 = gtk_vbox_new (FALSE, 0);
12131   gtk_container_add (GTK_CONTAINER (window), box1);
12132
12133   if (gtk_micro_version > 0)
12134     sprintf (buffer,
12135              "Gtk+ v%d.%d.%d",
12136              gtk_major_version,
12137              gtk_minor_version,
12138              gtk_micro_version);
12139   else
12140     sprintf (buffer,
12141              "Gtk+ v%d.%d",
12142              gtk_major_version,
12143              gtk_minor_version);
12144
12145   label = gtk_label_new (buffer);
12146   gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
12147   gtk_widget_set_name (label, "testgtk-version-label");
12148
12149   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
12150   gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
12151   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
12152                                   GTK_POLICY_NEVER, 
12153                                   GTK_POLICY_AUTOMATIC);
12154   gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
12155
12156   box2 = gtk_vbox_new (FALSE, 0);
12157   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12158   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box2);
12159   gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
12160                                        gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
12161   gtk_widget_show (box2);
12162
12163   for (i = 0; i < nbuttons; i++)
12164     {
12165       button = gtk_button_new_with_label (buttons[i].label);
12166       if (buttons[i].func)
12167         gtk_signal_connect (GTK_OBJECT (button), 
12168                             "clicked", 
12169                             GTK_SIGNAL_FUNC(buttons[i].func),
12170                             NULL);
12171       else
12172         gtk_widget_set_sensitive (button, FALSE);
12173       gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12174     }
12175
12176   separator = gtk_hseparator_new ();
12177   gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
12178
12179   box2 = gtk_vbox_new (FALSE, 10);
12180   gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
12181   gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
12182
12183   button = gtk_button_new_with_mnemonic ("_Close");
12184   gtk_signal_connect (GTK_OBJECT (button), "clicked",
12185                       GTK_SIGNAL_FUNC (do_exit),
12186                       window);
12187   gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
12188   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
12189   gtk_widget_grab_default (button);
12190
12191   gtk_widget_show_all (window);
12192 }
12193
12194 static void
12195 test_init ()
12196 {
12197   if (g_file_test ("../gdk-pixbuf/libpixbufloader-pnm.la",
12198                    G_FILE_TEST_EXISTS))
12199     {
12200       putenv ("GDK_PIXBUF_MODULE_FILE=../gdk-pixbuf/gdk-pixbuf.loaders");
12201       putenv ("GTK_IM_MODULE_FILE=../modules/input/gtk.immodules");
12202     }
12203 }
12204
12205 static char *
12206 pad (const char *str, int to)
12207 {
12208   static char buf[256];
12209   int len = strlen (str);
12210   int i;
12211
12212   for (i = 0; i < to; i++)
12213     buf[i] = ' ';
12214
12215   buf[to] = '\0';
12216
12217   memcpy (buf, str, len);
12218
12219   return buf;
12220 }
12221
12222 static void
12223 bench_iteration (void (* fn) ())
12224 {
12225   fn (); /* on */
12226   while (g_main_iteration (FALSE));
12227   fn (); /* off */
12228   while (g_main_iteration (FALSE));
12229 }
12230
12231 void
12232 do_real_bench (void (* fn) (), char *name, int num)
12233 {
12234   GTimeVal tv0, tv1;
12235   double dt_first;
12236   double dt;
12237   int n;
12238   static gboolean printed_headers = FALSE;
12239
12240   if (!printed_headers) {
12241     g_print ("Test                 Iters      First      Other\n");
12242     g_print ("-------------------- ----- ---------- ----------\n");
12243     printed_headers = TRUE;
12244   }
12245
12246   g_get_current_time (&tv0);
12247   bench_iteration (fn); 
12248   g_get_current_time (&tv1);
12249
12250   dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12251         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12252
12253   g_get_current_time (&tv0);
12254   for (n = 0; n < num - 1; n++)
12255     bench_iteration (fn); 
12256   g_get_current_time (&tv1);
12257   dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
12258         + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
12259
12260   g_print ("%s %5d ", pad (name, 20), num);
12261   if (num > 1)
12262     g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
12263   else
12264     g_print ("%10.1f\n", dt_first);
12265 }
12266
12267 void
12268 do_bench (char* what, int num)
12269 {
12270   int i;
12271   void (* fn) ();
12272   fn = NULL;
12273
12274   if (g_strcasecmp (what, "ALL") == 0)
12275     {
12276       for (i = 0; i < nbuttons; i++)
12277         {
12278           if (!buttons[i].do_not_benchmark)
12279             do_real_bench (buttons[i].func, buttons[i].label, num);
12280         }
12281
12282       return;
12283     }
12284   else
12285     {
12286       for (i = 0; i < nbuttons; i++)
12287         {
12288           if (strcmp (buttons[i].label, what) == 0)
12289             {
12290               fn = buttons[i].func;
12291               break;
12292             }
12293         }
12294       
12295       if (!fn)
12296         g_print ("Can't bench: \"%s\" not found.\n", what);
12297       else
12298         do_real_bench (fn, buttons[i].label, num);
12299     }
12300 }
12301
12302 void 
12303 usage (void)
12304 {
12305   fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
12306   exit (1);
12307 }
12308
12309 int
12310 main (int argc, char *argv[])
12311 {
12312   GtkBindingSet *binding_set;
12313   int i;
12314   gboolean done_benchmarks = FALSE;
12315
12316   srand (time (NULL));
12317
12318   test_init ();
12319
12320   /* Check to see if we are being run from the correct
12321    * directory.
12322    */
12323   if (file_exists ("testgtkrc"))
12324     gtk_rc_add_default_file ("testgtkrc");
12325
12326   gtk_init (&argc, &argv);
12327
12328   /*  benchmarking
12329    */
12330   for (i = 1; i < argc; i++)
12331     {
12332       if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
12333         {
12334           int num = 1;
12335           char *nextarg;
12336           char *what;
12337           char *count;
12338           
12339           nextarg = strchr (argv[i], '=');
12340           if (nextarg)
12341             nextarg++;
12342           else
12343             {
12344               i++;
12345               if (i == argc)
12346                 usage ();
12347               nextarg = argv[i];
12348             }
12349
12350           count = strchr (nextarg, ':');
12351           if (count)
12352             {
12353               what = g_strndup (nextarg, count - nextarg);
12354               count++;
12355               num = atoi (count);
12356               if (num <= 0)
12357                 usage ();
12358             }
12359           else
12360             what = g_strdup (nextarg);
12361
12362           do_bench (what, num ? num : 1);
12363           done_benchmarks = TRUE;
12364         }
12365       else
12366         usage ();
12367     }
12368   if (done_benchmarks)
12369     return 0;
12370
12371   /* bindings test
12372    */
12373   binding_set = gtk_binding_set_by_class (gtk_type_class (GTK_TYPE_WIDGET));
12374   gtk_binding_entry_add_signal (binding_set,
12375                                 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
12376                                 "debug_msg",
12377                                 1,
12378                                 GTK_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
12379   
12380   /* We use gtk_rc_parse_string() here so we can make sure it works across theme
12381    * changes
12382    */
12383
12384   gtk_rc_parse_string ("style \"testgtk-version-label\" { "
12385                        "   fg[NORMAL] = \"#ff0000\"\n"
12386                        "   font = \"Sans 18\"\n"
12387                        "}\n"
12388                        "widget \"*.testgtk-version-label\" style \"testgtk-version-label\"");
12389   
12390   create_main_window ();
12391
12392   gtk_main ();
12393
12394   if (1)
12395     {
12396       while (g_main_pending ())
12397         g_main_iteration (FALSE);
12398 #if 0
12399       sleep (1);
12400       while (g_main_pending ())
12401         g_main_iteration (FALSE);
12402 #endif
12403     }
12404   return 0;
12405 }