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