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