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