]> Pileus Git - ~andy/gtk/blob - gtk/gtkwidget.c
57c5d38b44b58e967c58b2a51976dfb059634706
[~andy/gtk] / gtk / gtkwidget.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <stdarg.h>
28 #include <string.h>
29 #include <locale.h>
30 #include "gtkcontainer.h"
31 #include "gtkaccelmap.h"
32 #include "gtkiconfactory.h"
33 #include "gtkintl.h"
34 #include "gtkmain.h"
35 #include "gtkmarshalers.h"
36 #include "gtkrc.h"
37 #include "gtkselection.h"
38 #include "gtksettings.h"
39 #include "gtksizegroup.h"
40 #include "gtksignal.h"
41 #include "gtkwidget.h"
42 #include "gtkwindow.h"
43 #include "gtkbindings.h"
44 #include "gtkprivate.h"
45 #include "gdk/gdk.h"
46 #include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
47 #include <gobject/gvaluecollector.h>
48 #include <gobject/gobjectnotifyqueue.c>
49 #include "gdk/gdkkeysyms.h"
50 #include "gtkintl.h"
51 #include "gtkaccessible.h"
52 #include "gtktooltips.h"
53
54 #define WIDGET_CLASS(w)  GTK_WIDGET_GET_CLASS (w)
55 #define INIT_PATH_SIZE  (512)
56
57
58 enum {
59   SHOW,
60   HIDE,
61   MAP,
62   UNMAP,
63   REALIZE,
64   UNREALIZE,
65   SIZE_REQUEST,
66   SIZE_ALLOCATE,
67   STATE_CHANGED,
68   PARENT_SET,
69   HIERARCHY_CHANGED,
70   STYLE_SET,
71   DIRECTION_CHANGED,
72   GRAB_NOTIFY,
73   CHILD_NOTIFY,
74   MNEMONIC_ACTIVATE,
75   GRAB_FOCUS,
76   FOCUS,
77   EVENT,
78   EVENT_AFTER,
79   BUTTON_PRESS_EVENT,
80   BUTTON_RELEASE_EVENT,
81   SCROLL_EVENT,
82   MOTION_NOTIFY_EVENT,
83   DELETE_EVENT,
84   DESTROY_EVENT,
85   EXPOSE_EVENT,
86   KEY_PRESS_EVENT,
87   KEY_RELEASE_EVENT,
88   ENTER_NOTIFY_EVENT,
89   LEAVE_NOTIFY_EVENT,
90   CONFIGURE_EVENT,
91   FOCUS_IN_EVENT,
92   FOCUS_OUT_EVENT,
93   MAP_EVENT,
94   UNMAP_EVENT,
95   PROPERTY_NOTIFY_EVENT,
96   SELECTION_CLEAR_EVENT,
97   SELECTION_REQUEST_EVENT,
98   SELECTION_NOTIFY_EVENT,
99   SELECTION_GET,
100   SELECTION_RECEIVED,
101   PROXIMITY_IN_EVENT,
102   PROXIMITY_OUT_EVENT,
103   DRAG_BEGIN,
104   DRAG_END,
105   DRAG_DATA_DELETE,
106   DRAG_LEAVE,
107   DRAG_MOTION,
108   DRAG_DROP,
109   DRAG_DATA_GET,
110   DRAG_DATA_RECEIVED,
111   CLIENT_EVENT,
112   NO_EXPOSE_EVENT,
113   VISIBILITY_NOTIFY_EVENT,
114   WINDOW_STATE_EVENT,
115   POPUP_MENU,
116   SHOW_HELP,
117   ACCEL_CLOSURES_CHANGED,
118   LAST_SIGNAL
119 };
120
121 enum {
122   PROP_0,
123   PROP_NAME,
124   PROP_PARENT,
125   PROP_WIDTH_REQUEST,
126   PROP_HEIGHT_REQUEST,
127   PROP_VISIBLE,
128   PROP_SENSITIVE,
129   PROP_APP_PAINTABLE,
130   PROP_CAN_FOCUS,
131   PROP_HAS_FOCUS,
132   PROP_CAN_DEFAULT,
133   PROP_HAS_DEFAULT,
134   PROP_RECEIVES_DEFAULT,
135   PROP_COMPOSITE_CHILD,
136   PROP_STYLE,
137   PROP_EVENTS,
138   PROP_EXTENSION_EVENTS
139 };
140
141 typedef struct  _GtkStateData    GtkStateData;
142
143 struct _GtkStateData
144 {
145   GtkStateType  state;
146   guint         state_restoration : 1;
147   guint         parent_sensitive : 1;
148   guint         use_forall : 1;
149 };
150
151
152 /* --- prototypes --- */
153 static void     gtk_widget_class_init            (GtkWidgetClass    *klass);
154 static void     gtk_widget_init                  (GtkWidget         *widget);
155 static void     gtk_widget_set_property          (GObject           *object,
156                                                   guint              prop_id,
157                                                   const GValue      *value,
158                                                   GParamSpec        *pspec);
159 static void     gtk_widget_get_property          (GObject           *object,
160                                                   guint              prop_id,
161                                                   GValue            *value,
162                                                   GParamSpec        *pspec);
163 static void     gtk_widget_dispose               (GObject           *object);
164 static void     gtk_widget_real_destroy          (GtkObject         *object);
165 static void     gtk_widget_finalize              (GObject           *object);
166 static void     gtk_widget_real_show             (GtkWidget         *widget);
167 static void     gtk_widget_real_hide             (GtkWidget         *widget);
168 static void     gtk_widget_real_map              (GtkWidget         *widget);
169 static void     gtk_widget_real_unmap            (GtkWidget         *widget);
170 static void     gtk_widget_real_realize          (GtkWidget         *widget);
171 static void     gtk_widget_real_unrealize        (GtkWidget         *widget);
172 static void     gtk_widget_real_size_request     (GtkWidget         *widget,
173                                                   GtkRequisition    *requisition);
174 static void     gtk_widget_real_size_allocate    (GtkWidget         *widget,
175                                                   GtkAllocation     *allocation);
176 static void     gtk_widget_style_set             (GtkWidget         *widget,
177                                                   GtkStyle          *previous_style);
178 static void     gtk_widget_direction_changed     (GtkWidget         *widget,
179                                                   GtkTextDirection   previous_direction);
180
181 static void     gtk_widget_real_grab_focus       (GtkWidget         *focus_widget);
182 static gboolean gtk_widget_real_show_help        (GtkWidget         *widget,
183                                                   GtkWidgetHelpType  help_type);
184
185 static void     gtk_widget_dispatch_child_properties_changed    (GtkWidget        *object,
186                                                                  guint             n_pspecs,
187                                                                  GParamSpec      **pspecs);
188 static gboolean         gtk_widget_real_key_press_event         (GtkWidget        *widget,
189                                                                  GdkEventKey      *event);
190 static gboolean         gtk_widget_real_key_release_event       (GtkWidget        *widget,
191                                                                  GdkEventKey      *event);
192 static gboolean         gtk_widget_real_focus_in_event           (GtkWidget       *widget,
193                                                                   GdkEventFocus   *event);
194 static gboolean         gtk_widget_real_focus_out_event         (GtkWidget        *widget,
195                                                                  GdkEventFocus    *event);
196 static gboolean         gtk_widget_real_focus                   (GtkWidget        *widget,
197                                                                  GtkDirectionType  direction);
198 static PangoContext*    gtk_widget_peek_pango_context           (GtkWidget        *widget);
199 static void             gtk_widget_reparent_container_child     (GtkWidget        *widget,
200                                                                  gpointer          client_data);
201 static void             gtk_widget_propagate_state              (GtkWidget        *widget,
202                                                                  GtkStateData     *data);
203 static void             gtk_widget_reset_rc_style               (GtkWidget        *widget);
204 static void             gtk_widget_set_style_internal           (GtkWidget        *widget,
205                                                                  GtkStyle         *style,
206                                                                  gboolean          initial_emission);
207 static gint             gtk_widget_event_internal               (GtkWidget        *widget,
208                                                                  GdkEvent         *event);
209 static gboolean         gtk_widget_real_mnemonic_activate       (GtkWidget        *widget,
210                                                                  gboolean          group_cycling);
211 static void             gtk_widget_aux_info_destroy             (GtkWidgetAuxInfo *aux_info);
212 static AtkObject*       gtk_widget_real_get_accessible          (GtkWidget        *widget);
213 static void             gtk_widget_accessible_interface_init    (AtkImplementorIface *iface);
214 static AtkObject*       gtk_widget_ref_accessible               (AtkImplementor *implementor);
215 static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
216                                                                  GdkRegion        *region);
217
218
219 /* --- variables --- */
220 static gpointer         parent_class = NULL;
221 static guint            widget_signals[LAST_SIGNAL] = { 0 };
222 static GMemChunk       *aux_info_mem_chunk = NULL;
223 static GdkColormap     *default_colormap = NULL;
224 static GtkStyle        *gtk_default_style = NULL;
225 static GSList          *colormap_stack = NULL;
226 static guint            composite_child_stack = 0;
227 static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
228 static GParamSpecPool  *style_property_spec_pool = NULL;
229
230 static GQuark           quark_property_parser = 0;
231 static GQuark           quark_aux_info = 0;
232 static GQuark           quark_accel_path = 0;
233 static GQuark           quark_accel_closures = 0;
234 static GQuark           quark_event_mask = 0;
235 static GQuark           quark_extension_event_mode = 0;
236 static GQuark           quark_parent_window = 0;
237 static GQuark           quark_shape_info = 0;
238 static GQuark           quark_colormap = 0;
239 static GQuark           quark_pango_context = 0;
240 static GQuark           quark_rc_style = 0;
241 static GQuark           quark_accessible_object = 0;
242 GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
243 GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
244
245 /* --- functions --- */
246 GtkType
247 gtk_widget_get_type (void)
248 {
249   static GtkType widget_type = 0;
250   
251   if (!widget_type)
252     {
253       static const GtkTypeInfo widget_info =
254       {
255         "GtkWidget",
256         sizeof (GtkWidget),
257         sizeof (GtkWidgetClass),
258         (GtkClassInitFunc) gtk_widget_class_init,
259         (GtkObjectInitFunc) gtk_widget_init,
260         /* reserved_1 */ NULL,
261         /* reserved_2 */ NULL,
262         (GtkClassInitFunc) NULL,
263       };
264       
265       static const GInterfaceInfo accessibility_info =
266       {
267         (GInterfaceInitFunc) gtk_widget_accessible_interface_init,
268         (GInterfaceFinalizeFunc) NULL,
269         NULL /* interface data */
270       };
271
272  
273       widget_type = gtk_type_unique (GTK_TYPE_OBJECT, &widget_info);
274
275       g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
276                                    &accessibility_info) ;
277
278     }
279   
280   return widget_type;
281 }
282
283 static void
284 child_property_notify_dispatcher (GObject     *object,
285                                   guint        n_pspecs,
286                                   GParamSpec **pspecs)
287 {
288   GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
289 }
290
291 static void
292 gtk_widget_class_init (GtkWidgetClass *klass)
293 {
294   static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
295   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
296   GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
297   GtkBindingSet *binding_set;
298   
299   parent_class = g_type_class_peek_parent (klass);
300
301   quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
302   quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
303   quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
304   quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
305   quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
306   quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
307   quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
308   quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
309   quark_colormap = g_quark_from_static_string ("gtk-colormap");
310   quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
311   quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
312   quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
313
314   style_property_spec_pool = g_param_spec_pool_new (FALSE);
315   _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
316   cpn_context.quark_notify_queue = g_quark_from_static_string ("GtkWidget-child-property-notify-queue");
317   cpn_context.dispatcher = child_property_notify_dispatcher;
318   _gtk_widget_child_property_notify_context = &cpn_context;
319
320   gobject_class->dispose = gtk_widget_dispose;
321   gobject_class->finalize = gtk_widget_finalize;
322   gobject_class->set_property = gtk_widget_set_property;
323   gobject_class->get_property = gtk_widget_get_property;
324
325   object_class->destroy = gtk_widget_real_destroy;
326   
327   klass->activate_signal = 0;
328   klass->set_scroll_adjustments_signal = 0;
329   klass->dispatch_child_properties_changed = gtk_widget_dispatch_child_properties_changed;
330   klass->show = gtk_widget_real_show;
331   klass->show_all = gtk_widget_show;
332   klass->hide = gtk_widget_real_hide;
333   klass->hide_all = gtk_widget_hide;
334   klass->map = gtk_widget_real_map;
335   klass->unmap = gtk_widget_real_unmap;
336   klass->realize = gtk_widget_real_realize;
337   klass->unrealize = gtk_widget_real_unrealize;
338   klass->size_request = gtk_widget_real_size_request;
339   klass->size_allocate = gtk_widget_real_size_allocate;
340   klass->state_changed = NULL;
341   klass->parent_set = NULL;
342   klass->hierarchy_changed = NULL;
343   klass->style_set = gtk_widget_style_set;
344   klass->direction_changed = gtk_widget_direction_changed;
345   klass->grab_notify = NULL;
346   klass->child_notify = NULL;
347   klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
348   klass->grab_focus = gtk_widget_real_grab_focus;
349   klass->focus = gtk_widget_real_focus;
350   klass->event = NULL;
351   klass->button_press_event = NULL;
352   klass->button_release_event = NULL;
353   klass->motion_notify_event = NULL;
354   klass->delete_event = NULL;
355   klass->destroy_event = NULL;
356   klass->expose_event = NULL;
357   klass->key_press_event = gtk_widget_real_key_press_event;
358   klass->key_release_event = gtk_widget_real_key_release_event;
359   klass->enter_notify_event = NULL;
360   klass->leave_notify_event = NULL;
361   klass->configure_event = NULL;
362   klass->focus_in_event = gtk_widget_real_focus_in_event;
363   klass->focus_out_event = gtk_widget_real_focus_out_event;
364   klass->map_event = NULL;
365   klass->unmap_event = NULL;
366   klass->window_state_event = NULL;
367   klass->property_notify_event = gtk_selection_property_notify;
368   klass->selection_clear_event = gtk_selection_clear;
369   klass->selection_request_event = gtk_selection_request;
370   klass->selection_notify_event = gtk_selection_notify;
371   klass->selection_received = NULL;
372   klass->proximity_in_event = NULL;
373   klass->proximity_out_event = NULL;
374   klass->drag_begin = NULL;
375   klass->drag_end = NULL;
376   klass->drag_data_delete = NULL;
377   klass->drag_leave = NULL;
378   klass->drag_motion = NULL;
379   klass->drag_drop = NULL;
380   klass->drag_data_received = NULL;
381
382   klass->show_help = gtk_widget_real_show_help;
383   
384   /* Accessibility support */
385   klass->get_accessible = gtk_widget_real_get_accessible;
386
387   klass->no_expose_event = NULL;
388
389   g_object_class_install_property (gobject_class,
390                                    PROP_NAME,
391                                    g_param_spec_string ("name",
392                                                         _("Widget name"),
393                                                         _("The name of the widget"),
394                                                         NULL,
395                                                         G_PARAM_READWRITE));
396   g_object_class_install_property (gobject_class,
397                                    PROP_PARENT,
398                                    g_param_spec_object ("parent",
399                                                         _("Parent widget"),
400                                                         _("The parent widget of this widget. Must be a Container widget."),
401                                                         GTK_TYPE_CONTAINER,
402                                                         G_PARAM_READWRITE));
403
404   g_object_class_install_property (gobject_class,
405                                    PROP_WIDTH_REQUEST,
406                                    g_param_spec_int ("width_request",
407                                                      _("Width request"),
408                                                      _("Override for width request of the widget, or -1 if natural request should be used."),
409                                                      -1,
410                                                      G_MAXINT,
411                                                      -1,
412                                                      G_PARAM_READWRITE));
413   g_object_class_install_property (gobject_class,
414                                    PROP_HEIGHT_REQUEST,
415                                    g_param_spec_int ("height_request",
416                                                      _("Height request"),
417                                                      _("Override for height request of the widget, or -1 if natural request should be used."),
418                                                      -1,
419                                                      G_MAXINT,
420                                                      -1,
421                                                      G_PARAM_READWRITE));
422   g_object_class_install_property (gobject_class,
423                                    PROP_VISIBLE,
424                                    g_param_spec_boolean ("visible",
425                                                          _("Visible"),
426                                                          _("Whether the widget is visible"),
427                                                          FALSE,
428                                                          G_PARAM_READWRITE));
429   g_object_class_install_property (gobject_class,
430                                    PROP_SENSITIVE,
431                                    g_param_spec_boolean ("sensitive",
432                                                          _("Sensitive"),
433                                                          _("Whether the widget responds to input"),
434                                                          TRUE,
435                                                          G_PARAM_READWRITE));
436   g_object_class_install_property (gobject_class,
437                                    PROP_APP_PAINTABLE,
438                                    g_param_spec_boolean ("app_paintable",
439                                                          _("Application paintable"),
440                                                          _("Whether the application will paint directly on the widget"),
441                                                          FALSE,
442                                                          G_PARAM_READWRITE));
443   g_object_class_install_property (gobject_class,
444                                    PROP_CAN_FOCUS,
445                                    g_param_spec_boolean ("can_focus",
446                                                          _("Can focus"),
447                                                          _("Whether the widget can accept the input focus"),
448                                                          FALSE,
449                                                          G_PARAM_READWRITE));
450   g_object_class_install_property (gobject_class,
451                                    PROP_HAS_FOCUS,
452                                    g_param_spec_boolean ("has_focus",
453                                                          _("Has focus"),
454                                                          _("Whether the widget has the input focus"),
455                                                          FALSE,
456                                                          G_PARAM_READWRITE));
457   g_object_class_install_property (gobject_class,
458                                    PROP_CAN_DEFAULT,
459                                    g_param_spec_boolean ("can_default",
460                                                          _("Can default"),
461                                                          _("Whether the widget can be the default widget"),
462                                                          FALSE,
463                                                          G_PARAM_READWRITE));
464   g_object_class_install_property (gobject_class,
465                                    PROP_HAS_DEFAULT,
466                                    g_param_spec_boolean ("has_default",
467                                                          _("Has default"),
468                                                          _("Whether the widget is the default widget"),
469                                                          FALSE,
470                                                          G_PARAM_READWRITE));
471   g_object_class_install_property (gobject_class,
472                                    PROP_RECEIVES_DEFAULT,
473                                    g_param_spec_boolean ("receives_default",
474                                                          _("Receives default"),
475                                                          _("If TRUE, the widget will receive the default action when it is focused."),
476                                                          FALSE,
477                                                          G_PARAM_READWRITE));
478   g_object_class_install_property (gobject_class,
479                                    PROP_COMPOSITE_CHILD,
480                                    g_param_spec_boolean ("composite_child",
481                                                          _("Composite child"),
482                                                          _("Whether the widget is composed of other widgets"),
483                                                          FALSE,
484                                                          G_PARAM_READABLE));
485   g_object_class_install_property (gobject_class,
486                                    PROP_STYLE,
487                                    g_param_spec_object ("style",
488                                                         _("Style"),
489                                                         _("The style of the widget, which contains information about how it will look (colors etc)."),
490                                                         GTK_TYPE_STYLE,
491                                                         G_PARAM_READWRITE));
492   g_object_class_install_property (gobject_class,
493                                    PROP_EVENTS,
494                                    g_param_spec_flags ("events",
495                                                        _("Events"),
496                                                        _("The event mask that decides what kind of GdkEvents this widget gets."),
497                                                        GDK_TYPE_EVENT_MASK,
498                                                        GDK_STRUCTURE_MASK,
499                                                        G_PARAM_READWRITE));
500   g_object_class_install_property (gobject_class,
501                                    PROP_EXTENSION_EVENTS,
502                                    g_param_spec_enum ("extension_events",
503                                                       _("Extension events"),
504                                                       _("The mask that decides what kind of extension events this widget gets."),
505                                                       GDK_TYPE_EXTENSION_MODE,
506                                                       GDK_EXTENSION_EVENTS_NONE,
507                                                       G_PARAM_READWRITE));
508   widget_signals[SHOW] =
509     gtk_signal_new ("show",
510                     GTK_RUN_FIRST,
511                     GTK_CLASS_TYPE (object_class),
512                     GTK_SIGNAL_OFFSET (GtkWidgetClass, show),
513                     _gtk_marshal_VOID__VOID,
514                     GTK_TYPE_NONE, 0);
515   widget_signals[HIDE] =
516     gtk_signal_new ("hide",
517                     GTK_RUN_FIRST,
518                     GTK_CLASS_TYPE (object_class),
519                     GTK_SIGNAL_OFFSET (GtkWidgetClass, hide),
520                     _gtk_marshal_VOID__VOID,
521                     GTK_TYPE_NONE, 0);
522   widget_signals[MAP] =
523     gtk_signal_new ("map",
524                     GTK_RUN_FIRST,
525                     GTK_CLASS_TYPE (object_class),
526                     GTK_SIGNAL_OFFSET (GtkWidgetClass, map),
527                     _gtk_marshal_VOID__VOID,
528                     GTK_TYPE_NONE, 0);
529   widget_signals[UNMAP] =
530     gtk_signal_new ("unmap",
531                     GTK_RUN_FIRST,
532                     GTK_CLASS_TYPE (object_class),
533                     GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap),
534                     _gtk_marshal_VOID__VOID,
535                     GTK_TYPE_NONE, 0);
536   widget_signals[REALIZE] =
537     gtk_signal_new ("realize",
538                     GTK_RUN_FIRST,
539                     GTK_CLASS_TYPE (object_class),
540                     GTK_SIGNAL_OFFSET (GtkWidgetClass, realize),
541                     _gtk_marshal_VOID__VOID,
542                     GTK_TYPE_NONE, 0);
543   widget_signals[UNREALIZE] =
544     gtk_signal_new ("unrealize",
545                     GTK_RUN_LAST,
546                     GTK_CLASS_TYPE (object_class),
547                     GTK_SIGNAL_OFFSET (GtkWidgetClass, unrealize),
548                     _gtk_marshal_VOID__VOID,
549                     GTK_TYPE_NONE, 0);
550   widget_signals[SIZE_REQUEST] =
551     g_signal_new ("size_request",
552                    G_OBJECT_CLASS_TYPE (object_class),
553                    G_SIGNAL_RUN_FIRST,
554                    G_STRUCT_OFFSET (GtkWidgetClass, size_request),
555                    NULL, NULL,
556                    _gtk_marshal_VOID__BOXED,
557                    GTK_TYPE_NONE, 1,
558                    GTK_TYPE_REQUISITION | G_SIGNAL_TYPE_STATIC_SCOPE);
559   widget_signals[SIZE_ALLOCATE] = 
560     gtk_signal_new ("size_allocate",
561                     GTK_RUN_FIRST,
562                     GTK_CLASS_TYPE (object_class),
563                     GTK_SIGNAL_OFFSET (GtkWidgetClass, size_allocate),
564                     _gtk_marshal_VOID__BOXED,
565                     GTK_TYPE_NONE, 1,
566                     GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
567   widget_signals[STATE_CHANGED] =
568     gtk_signal_new ("state_changed",
569                     GTK_RUN_FIRST,
570                     GTK_CLASS_TYPE (object_class),
571                     GTK_SIGNAL_OFFSET (GtkWidgetClass, state_changed),
572                     _gtk_marshal_VOID__ENUM,
573                     GTK_TYPE_NONE, 1,
574                     GTK_TYPE_STATE_TYPE);
575   widget_signals[PARENT_SET] =
576     gtk_signal_new ("parent_set",
577                     GTK_RUN_FIRST,
578                     GTK_CLASS_TYPE (object_class),
579                     GTK_SIGNAL_OFFSET (GtkWidgetClass, parent_set),
580                     _gtk_marshal_VOID__OBJECT,
581                     GTK_TYPE_NONE, 1,
582                     GTK_TYPE_WIDGET);
583   widget_signals[HIERARCHY_CHANGED] =
584     gtk_signal_new ("hierarchy_changed",
585                     GTK_RUN_LAST,
586                     GTK_CLASS_TYPE (object_class),
587                     GTK_SIGNAL_OFFSET (GtkWidgetClass, hierarchy_changed),
588                     _gtk_marshal_VOID__OBJECT,
589                     GTK_TYPE_NONE, 1,
590                     GTK_TYPE_WIDGET);
591   widget_signals[STYLE_SET] =
592     gtk_signal_new ("style_set",
593                     GTK_RUN_FIRST,
594                     GTK_CLASS_TYPE (object_class),
595                     GTK_SIGNAL_OFFSET (GtkWidgetClass, style_set),
596                     _gtk_marshal_VOID__OBJECT,
597                     GTK_TYPE_NONE, 1,
598                     GTK_TYPE_STYLE);
599   widget_signals[DIRECTION_CHANGED] =
600     gtk_signal_new ("direction_changed",
601                     GTK_RUN_FIRST,
602                     GTK_CLASS_TYPE (object_class),
603                     GTK_SIGNAL_OFFSET (GtkWidgetClass, direction_changed),
604                     _gtk_marshal_VOID__ENUM,
605                     GTK_TYPE_NONE, 1,
606                     GTK_TYPE_TEXT_DIRECTION);
607   widget_signals[GRAB_NOTIFY] =
608     gtk_signal_new ("grab_notify",
609                     GTK_RUN_FIRST,
610                     GTK_CLASS_TYPE (object_class),
611                     GTK_SIGNAL_OFFSET (GtkWidgetClass, grab_notify),
612                     _gtk_marshal_VOID__BOOLEAN,
613                     GTK_TYPE_NONE, 1,
614                     GTK_TYPE_BOOL);
615   widget_signals[CHILD_NOTIFY] =
616     g_signal_new ("child_notify",
617                    G_TYPE_FROM_CLASS (klass),
618                    G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
619                    G_STRUCT_OFFSET (GtkWidgetClass, child_notify),
620                    NULL, NULL,
621                    g_cclosure_marshal_VOID__PARAM,
622                    G_TYPE_NONE,
623                    1, G_TYPE_PARAM);
624   widget_signals[MNEMONIC_ACTIVATE] =
625     g_signal_new ("mnemonic_activate",
626                   GTK_CLASS_TYPE (object_class),
627                   GTK_RUN_LAST,
628                   GTK_SIGNAL_OFFSET (GtkWidgetClass, mnemonic_activate),
629                   _gtk_boolean_handled_accumulator, NULL,
630                   _gtk_marshal_BOOLEAN__BOOLEAN,
631                   GTK_TYPE_BOOL, 1,
632                   GTK_TYPE_BOOL);
633   widget_signals[GRAB_FOCUS] =
634     gtk_signal_new ("grab_focus",
635                     GTK_RUN_LAST | GTK_RUN_ACTION,
636                     GTK_CLASS_TYPE (object_class),
637                     GTK_SIGNAL_OFFSET (GtkWidgetClass, grab_focus),
638                     _gtk_marshal_VOID__VOID,
639                     GTK_TYPE_NONE, 0);
640   widget_signals[FOCUS] =
641     g_signal_new ("focus",
642                   G_TYPE_FROM_CLASS (object_class),
643                   G_SIGNAL_RUN_LAST,
644                   G_STRUCT_OFFSET (GtkWidgetClass, focus),
645                   _gtk_boolean_handled_accumulator, NULL,
646                   _gtk_marshal_BOOLEAN__ENUM,
647                   G_TYPE_BOOLEAN, 1,
648                   GTK_TYPE_DIRECTION_TYPE);
649   widget_signals[EVENT] =
650     g_signal_new ("event",
651                   G_TYPE_FROM_CLASS (object_class),
652                   G_SIGNAL_RUN_LAST,
653                   G_STRUCT_OFFSET(GtkWidgetClass, event),
654                   _gtk_boolean_handled_accumulator, NULL,
655                   _gtk_marshal_BOOLEAN__BOXED,
656                   G_TYPE_BOOLEAN, 1,
657                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
658   widget_signals[EVENT_AFTER] =
659     g_signal_new ("event-after",
660                   G_TYPE_FROM_CLASS (object_class),
661                   0,
662                   0,
663                   NULL, NULL,
664                   _gtk_marshal_VOID__BOXED,
665                   G_TYPE_NONE, 1, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
666   widget_signals[BUTTON_PRESS_EVENT] =
667     g_signal_new ("button_press_event",
668                   G_TYPE_FROM_CLASS (object_class),
669                   G_SIGNAL_RUN_LAST,
670                   G_STRUCT_OFFSET(GtkWidgetClass, button_press_event),
671                   _gtk_boolean_handled_accumulator, NULL,
672                   _gtk_marshal_BOOLEAN__BOXED,
673                   G_TYPE_BOOLEAN, 1,
674                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
675   widget_signals[BUTTON_RELEASE_EVENT] =
676     g_signal_new ("button_release_event",
677                   G_TYPE_FROM_CLASS(object_class),
678                   G_SIGNAL_RUN_LAST,
679                   G_STRUCT_OFFSET(GtkWidgetClass, button_release_event),
680                   _gtk_boolean_handled_accumulator, NULL,
681                   _gtk_marshal_BOOLEAN__BOXED,
682                   G_TYPE_BOOLEAN, 1,
683                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
684   widget_signals[SCROLL_EVENT] =
685     g_signal_new ("scroll_event",
686                   G_TYPE_FROM_CLASS(object_class),
687                   G_SIGNAL_RUN_LAST,
688                   G_STRUCT_OFFSET(GtkWidgetClass, scroll_event),
689                   _gtk_boolean_handled_accumulator, NULL,
690                   _gtk_marshal_BOOLEAN__BOXED,
691                   G_TYPE_BOOLEAN, 1,
692                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
693   widget_signals[MOTION_NOTIFY_EVENT] =
694     g_signal_new ("motion_notify_event",
695                   G_TYPE_FROM_CLASS(object_class),
696                   G_SIGNAL_RUN_LAST,
697                   G_STRUCT_OFFSET(GtkWidgetClass, motion_notify_event),
698                   _gtk_boolean_handled_accumulator, NULL,
699                   _gtk_marshal_BOOLEAN__BOXED,
700                   G_TYPE_BOOLEAN, 1,
701                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
702   widget_signals[DELETE_EVENT] =
703     g_signal_new ("delete_event",
704                   G_TYPE_FROM_CLASS(object_class),
705                   G_SIGNAL_RUN_LAST,
706                   G_STRUCT_OFFSET(GtkWidgetClass, delete_event),
707                   _gtk_boolean_handled_accumulator, NULL,
708                   _gtk_marshal_BOOLEAN__BOXED,
709                   G_TYPE_BOOLEAN, 1,
710                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
711   widget_signals[DESTROY_EVENT] =
712     g_signal_new ("destroy_event",
713                   G_TYPE_FROM_CLASS(object_class),
714                   G_SIGNAL_RUN_LAST,
715                   G_STRUCT_OFFSET(GtkWidgetClass, destroy_event),
716                   _gtk_boolean_handled_accumulator, NULL,
717                   _gtk_marshal_BOOLEAN__BOXED,
718                   G_TYPE_BOOLEAN, 1,
719                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
720   widget_signals[EXPOSE_EVENT] =
721     g_signal_new ("expose_event",
722                   G_TYPE_FROM_CLASS(object_class),
723                   G_SIGNAL_RUN_LAST,
724                   G_STRUCT_OFFSET(GtkWidgetClass, expose_event),
725                   _gtk_boolean_handled_accumulator, NULL,
726                   _gtk_marshal_BOOLEAN__BOXED,
727                   G_TYPE_BOOLEAN, 1,
728                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
729   widget_signals[KEY_PRESS_EVENT] =
730     g_signal_new ("key_press_event",
731                   G_TYPE_FROM_CLASS(object_class),
732                   G_SIGNAL_RUN_LAST,
733                   G_STRUCT_OFFSET(GtkWidgetClass, key_press_event),
734                   _gtk_boolean_handled_accumulator, NULL,
735                   _gtk_marshal_BOOLEAN__BOXED,
736                   G_TYPE_BOOLEAN, 1,
737                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
738   widget_signals[KEY_RELEASE_EVENT] =
739     g_signal_new ("key_release_event",
740                   G_TYPE_FROM_CLASS(object_class),
741                   G_SIGNAL_RUN_LAST,
742                   G_STRUCT_OFFSET(GtkWidgetClass, key_release_event),
743                   _gtk_boolean_handled_accumulator, NULL,
744                   _gtk_marshal_BOOLEAN__BOXED,
745                   G_TYPE_BOOLEAN, 1,
746                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
747   widget_signals[ENTER_NOTIFY_EVENT] =
748     g_signal_new ("enter_notify_event",
749                   G_TYPE_FROM_CLASS(object_class),
750                   G_SIGNAL_RUN_LAST,
751                   G_STRUCT_OFFSET(GtkWidgetClass, enter_notify_event),
752                   _gtk_boolean_handled_accumulator, NULL,
753                   _gtk_marshal_BOOLEAN__BOXED,
754                   G_TYPE_BOOLEAN, 1,
755                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
756   widget_signals[LEAVE_NOTIFY_EVENT] =
757     g_signal_new ("leave_notify_event",
758                   G_TYPE_FROM_CLASS(object_class),
759                   G_SIGNAL_RUN_LAST,
760                   G_STRUCT_OFFSET(GtkWidgetClass, leave_notify_event),
761                   _gtk_boolean_handled_accumulator, NULL,
762                   _gtk_marshal_BOOLEAN__BOXED,
763                   G_TYPE_BOOLEAN, 1,
764                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
765   widget_signals[CONFIGURE_EVENT] =
766     g_signal_new ("configure_event",
767                   G_TYPE_FROM_CLASS(object_class),
768                   G_SIGNAL_RUN_LAST,
769                   G_STRUCT_OFFSET(GtkWidgetClass, configure_event),
770                   _gtk_boolean_handled_accumulator, NULL,
771                   _gtk_marshal_BOOLEAN__BOXED,
772                   G_TYPE_BOOLEAN, 1,
773                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
774   widget_signals[FOCUS_IN_EVENT] =
775     g_signal_new ("focus_in_event",
776                   G_TYPE_FROM_CLASS(object_class),
777                   G_SIGNAL_RUN_LAST,
778                   G_STRUCT_OFFSET(GtkWidgetClass, focus_in_event),
779                   _gtk_boolean_handled_accumulator, NULL,
780                   _gtk_marshal_BOOLEAN__BOXED,
781                   G_TYPE_BOOLEAN, 1,
782                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
783   widget_signals[FOCUS_OUT_EVENT] =
784     g_signal_new ("focus_out_event",
785                   G_TYPE_FROM_CLASS(object_class),
786                   G_SIGNAL_RUN_LAST,
787                   G_STRUCT_OFFSET(GtkWidgetClass, focus_out_event),
788                   _gtk_boolean_handled_accumulator, NULL,
789                   _gtk_marshal_BOOLEAN__BOXED,
790                   G_TYPE_BOOLEAN, 1,
791                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
792   widget_signals[MAP_EVENT] =
793     g_signal_new ("map_event",
794                   G_TYPE_FROM_CLASS(object_class),
795                   G_SIGNAL_RUN_LAST,
796                   G_STRUCT_OFFSET(GtkWidgetClass, map_event),
797                   _gtk_boolean_handled_accumulator, NULL,
798                   _gtk_marshal_BOOLEAN__BOXED,
799                   G_TYPE_BOOLEAN, 1,
800                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
801   widget_signals[UNMAP_EVENT] =
802     g_signal_new ("unmap_event",
803                   G_TYPE_FROM_CLASS(object_class),
804                   G_SIGNAL_RUN_LAST,
805                   G_STRUCT_OFFSET(GtkWidgetClass, unmap_event),
806                   _gtk_boolean_handled_accumulator, NULL,
807                   _gtk_marshal_BOOLEAN__BOXED,
808                   G_TYPE_BOOLEAN, 1,
809                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
810   widget_signals[PROPERTY_NOTIFY_EVENT] =
811     g_signal_new ("property_notify_event",
812                   G_TYPE_FROM_CLASS(object_class),
813                   G_SIGNAL_RUN_LAST,
814                   G_STRUCT_OFFSET(GtkWidgetClass, property_notify_event),
815                   _gtk_boolean_handled_accumulator, NULL,
816                   _gtk_marshal_BOOLEAN__BOXED,
817                   G_TYPE_BOOLEAN, 1,
818                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
819   widget_signals[SELECTION_CLEAR_EVENT] =
820     g_signal_new ("selection_clear_event",
821                   G_TYPE_FROM_CLASS(object_class),
822                   G_SIGNAL_RUN_LAST,
823                   G_STRUCT_OFFSET(GtkWidgetClass, selection_clear_event),
824                   _gtk_boolean_handled_accumulator, NULL,
825                   _gtk_marshal_BOOLEAN__BOXED,
826                   G_TYPE_BOOLEAN, 1,
827                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
828   widget_signals[SELECTION_REQUEST_EVENT] =
829     g_signal_new ("selection_request_event",
830                   G_TYPE_FROM_CLASS(object_class),
831                   G_SIGNAL_RUN_LAST,
832                   G_STRUCT_OFFSET(GtkWidgetClass, selection_request_event),
833                   _gtk_boolean_handled_accumulator, NULL,
834                   _gtk_marshal_BOOLEAN__BOXED,
835                   G_TYPE_BOOLEAN, 1,
836                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
837   widget_signals[SELECTION_NOTIFY_EVENT] =
838     g_signal_new ("selection_notify_event",
839                   G_TYPE_FROM_CLASS(object_class),
840                   G_SIGNAL_RUN_LAST,
841                   G_STRUCT_OFFSET(GtkWidgetClass, selection_notify_event),
842                   _gtk_boolean_handled_accumulator, NULL,
843                   _gtk_marshal_BOOLEAN__BOXED,
844                   G_TYPE_BOOLEAN, 1,
845                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
846   widget_signals[SELECTION_RECEIVED] =
847     g_signal_new ("selection_received",
848                   G_TYPE_FROM_CLASS (object_class),
849                   G_SIGNAL_RUN_LAST,
850                   G_STRUCT_OFFSET (GtkWidgetClass, selection_received),
851                   NULL, NULL,
852                   _gtk_marshal_VOID__BOXED_UINT,
853                   G_TYPE_NONE, 2,
854                   GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
855                   G_TYPE_UINT);
856   widget_signals[SELECTION_GET] =
857     g_signal_new ("selection_get",
858                   G_TYPE_FROM_CLASS (object_class),
859                   G_SIGNAL_RUN_LAST,
860                   G_STRUCT_OFFSET (GtkWidgetClass, selection_get),
861                   NULL, NULL,
862                   _gtk_marshal_VOID__BOXED_UINT_UINT,
863                   G_TYPE_NONE, 3,
864                   GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
865                   G_TYPE_UINT,
866                   G_TYPE_UINT);
867   widget_signals[PROXIMITY_IN_EVENT] =
868     g_signal_new ("proximity_in_event",
869                   G_TYPE_FROM_CLASS (object_class),
870                   G_SIGNAL_RUN_LAST,
871                   G_STRUCT_OFFSET(GtkWidgetClass, proximity_in_event),
872                   _gtk_boolean_handled_accumulator, NULL,
873                   _gtk_marshal_BOOLEAN__BOXED,
874                   G_TYPE_BOOLEAN, 1,
875                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
876   widget_signals[PROXIMITY_OUT_EVENT] =
877     g_signal_new ("proximity_out_event",
878                   G_TYPE_FROM_CLASS(object_class),
879                   G_SIGNAL_RUN_LAST,
880                   G_STRUCT_OFFSET(GtkWidgetClass, proximity_out_event),
881                   _gtk_boolean_handled_accumulator, NULL,
882                   _gtk_marshal_BOOLEAN__BOXED,
883                   G_TYPE_BOOLEAN, 1,
884                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
885   widget_signals[DRAG_LEAVE] =
886     gtk_signal_new ("drag_leave",
887                     GTK_RUN_LAST,
888                     GTK_CLASS_TYPE (object_class),
889                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_leave),
890                     _gtk_marshal_VOID__OBJECT_UINT,
891                     GTK_TYPE_NONE, 2,
892                     GDK_TYPE_DRAG_CONTEXT,
893                     GTK_TYPE_UINT);
894   widget_signals[DRAG_BEGIN] =
895     gtk_signal_new ("drag_begin",
896                     GTK_RUN_LAST,
897                     GTK_CLASS_TYPE (object_class),
898                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin),
899                     _gtk_marshal_VOID__OBJECT,
900                     GTK_TYPE_NONE, 1,
901                     GDK_TYPE_DRAG_CONTEXT);
902   widget_signals[DRAG_END] =
903     gtk_signal_new ("drag_end",
904                     GTK_RUN_LAST,
905                     GTK_CLASS_TYPE (object_class),
906                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end),
907                     _gtk_marshal_VOID__OBJECT,
908                     GTK_TYPE_NONE, 1,
909                     GDK_TYPE_DRAG_CONTEXT);
910   widget_signals[DRAG_DATA_DELETE] =
911     gtk_signal_new ("drag_data_delete",
912                     GTK_RUN_LAST,
913                     GTK_CLASS_TYPE (object_class),
914                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_delete),
915                     _gtk_marshal_VOID__OBJECT,
916                     GTK_TYPE_NONE, 1,
917                     GDK_TYPE_DRAG_CONTEXT);
918   widget_signals[DRAG_MOTION] =
919     g_signal_new ("drag_motion",
920                   G_TYPE_FROM_CLASS(object_class),
921                   G_SIGNAL_RUN_LAST,
922                   G_STRUCT_OFFSET(GtkWidgetClass, drag_motion),
923                   _gtk_boolean_handled_accumulator, NULL,
924                   _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
925                   G_TYPE_BOOLEAN, 4,
926                   GDK_TYPE_DRAG_CONTEXT,
927                   G_TYPE_INT,
928                   G_TYPE_INT,
929                   G_TYPE_UINT);
930   widget_signals[DRAG_DROP] =
931     g_signal_new ("drag_drop",
932                   G_TYPE_FROM_CLASS(object_class),
933                   G_SIGNAL_RUN_LAST,
934                   G_STRUCT_OFFSET(GtkWidgetClass, drag_drop),
935                   _gtk_boolean_handled_accumulator, NULL,
936                   _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
937                   G_TYPE_BOOLEAN, 4,
938                   GDK_TYPE_DRAG_CONTEXT,
939                   G_TYPE_INT,
940                   G_TYPE_INT,
941                   G_TYPE_UINT);
942   widget_signals[DRAG_DATA_GET] =
943     g_signal_new ("drag_data_get",
944                   G_TYPE_FROM_CLASS (object_class),
945                   G_SIGNAL_RUN_LAST,
946                   G_STRUCT_OFFSET (GtkWidgetClass, drag_data_get),
947                   NULL, NULL,
948                   _gtk_marshal_VOID__OBJECT_BOXED_UINT_UINT,
949                   G_TYPE_NONE, 4,
950                   GDK_TYPE_DRAG_CONTEXT,
951                   GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
952                   G_TYPE_UINT,
953                   G_TYPE_UINT);
954   widget_signals[DRAG_DATA_RECEIVED] =
955     g_signal_new ("drag_data_received",
956                   G_TYPE_FROM_CLASS (object_class),
957                   G_SIGNAL_RUN_LAST,
958                   GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_received),
959                   NULL, NULL,
960                   _gtk_marshal_VOID__OBJECT_INT_INT_BOXED_UINT_UINT,
961                   G_TYPE_NONE, 6,
962                   GDK_TYPE_DRAG_CONTEXT,
963                   G_TYPE_INT,
964                   G_TYPE_INT,
965                   GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
966                   G_TYPE_UINT,
967                   G_TYPE_UINT);
968   widget_signals[VISIBILITY_NOTIFY_EVENT] =
969     g_signal_new ("visibility_notify_event",
970                   G_TYPE_FROM_CLASS(object_class),
971                   G_SIGNAL_RUN_LAST,
972                   G_STRUCT_OFFSET(GtkWidgetClass, visibility_notify_event),
973                   _gtk_boolean_handled_accumulator, NULL,
974                   _gtk_marshal_BOOLEAN__BOXED,
975                   G_TYPE_BOOLEAN, 1,
976                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
977   widget_signals[CLIENT_EVENT] =
978     g_signal_new ("client_event",
979                   G_TYPE_FROM_CLASS(object_class),
980                   G_SIGNAL_RUN_LAST,
981                   G_STRUCT_OFFSET(GtkWidgetClass, client_event),
982                   _gtk_boolean_handled_accumulator, NULL,
983                   _gtk_marshal_BOOLEAN__BOXED,
984                   G_TYPE_BOOLEAN, 1,
985                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
986   widget_signals[NO_EXPOSE_EVENT] =
987     g_signal_new ("no_expose_event",
988                   G_TYPE_FROM_CLASS(object_class),
989                   G_SIGNAL_RUN_LAST,
990                   G_STRUCT_OFFSET(GtkWidgetClass, no_expose_event),
991                   _gtk_boolean_handled_accumulator, NULL,
992                   _gtk_marshal_BOOLEAN__BOXED,
993                   G_TYPE_BOOLEAN, 1,
994                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
995   widget_signals[WINDOW_STATE_EVENT] =
996     g_signal_new ("window_state_event",
997                   G_TYPE_FROM_CLASS(object_class),
998                   G_SIGNAL_RUN_LAST,
999                   G_STRUCT_OFFSET(GtkWidgetClass, window_state_event),
1000                   _gtk_boolean_handled_accumulator, NULL,
1001                   _gtk_marshal_BOOLEAN__BOXED,
1002                   G_TYPE_BOOLEAN, 1,
1003                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1004   widget_signals[POPUP_MENU] =
1005     g_signal_new ("popup_menu",
1006                   G_TYPE_FROM_CLASS (object_class),
1007                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1008                   GTK_SIGNAL_OFFSET (GtkWidgetClass, popup_menu),
1009                   _gtk_boolean_handled_accumulator, NULL,
1010                   _gtk_marshal_BOOLEAN__VOID,
1011                   G_TYPE_BOOLEAN, 0);
1012   widget_signals[SHOW_HELP] =
1013     g_signal_new ("show_help",
1014                   G_TYPE_FROM_CLASS (object_class),
1015                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1016                   GTK_SIGNAL_OFFSET (GtkWidgetClass, show_help),
1017                   _gtk_boolean_handled_accumulator, NULL,
1018                   _gtk_marshal_BOOLEAN__ENUM,
1019                   G_TYPE_BOOLEAN, 1, GTK_TYPE_WIDGET_HELP_TYPE);
1020   widget_signals[ACCEL_CLOSURES_CHANGED] =
1021     gtk_signal_new ("accel_closures_changed",
1022                     0,
1023                     GTK_CLASS_TYPE (object_class),
1024                     0,
1025                     gtk_marshal_NONE__NONE,
1026                     GTK_TYPE_NONE, 0);
1027   
1028   binding_set = gtk_binding_set_by_class (klass);
1029   gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
1030                                 "popup_menu", 0);
1031   gtk_binding_entry_add_signal (binding_set, GDK_Menu, 0,
1032                                 "popup_menu", 0);  
1033
1034   gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_CONTROL_MASK,
1035                                 "show_help", 1,
1036                                 GTK_TYPE_WIDGET_HELP_TYPE,
1037                                 GTK_WIDGET_HELP_TOOLTIP);
1038   gtk_binding_entry_add_signal (binding_set, GDK_KP_F1, GDK_CONTROL_MASK,
1039                                 "show_help", 1,
1040                                 GTK_TYPE_WIDGET_HELP_TYPE,
1041                                 GTK_WIDGET_HELP_TOOLTIP);
1042   gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_SHIFT_MASK,
1043                                 "show_help", 1,
1044                                 GTK_TYPE_WIDGET_HELP_TYPE,
1045                                 GTK_WIDGET_HELP_WHATS_THIS);  
1046   gtk_binding_entry_add_signal (binding_set, GDK_KP_F1, GDK_SHIFT_MASK,
1047                                 "show_help", 1,
1048                                 GTK_TYPE_WIDGET_HELP_TYPE,
1049                                 GTK_WIDGET_HELP_WHATS_THIS);
1050
1051   gtk_widget_class_install_style_property (klass,
1052                                            g_param_spec_boolean ("interior_focus",
1053                                                                  _("Interior Focus"),
1054                                                                  _("Whether to draw the focus indicator inside widgets."),
1055                                                                  TRUE,
1056                                                                  G_PARAM_READABLE));
1057
1058   gtk_widget_class_install_style_property (klass,
1059                                            g_param_spec_int ("focus-line-width",
1060                                                              _("Focus linewidth"),
1061                                                              _("Width, in pixels, of the focus indicator line."),
1062                                                              0, G_MAXINT, 1,
1063                                                              G_PARAM_READWRITE));
1064
1065   gtk_widget_class_install_style_property (klass,
1066                                            g_param_spec_string ("focus-line-pattern",
1067                                                                 _("Focus line dash pattern"),
1068                                                                 _("Dash pattern used to draw the focus indicator."),
1069                                                                 "\1\1",
1070                                                                 G_PARAM_READWRITE));
1071   gtk_widget_class_install_style_property (klass,
1072                                            g_param_spec_int ("focus-padding",
1073                                                              _("Focus padding"),
1074                                                              _("Width, in pixels, between focus indicator and the widget 'box'."),
1075                                                              0, G_MAXINT, 1,
1076                                                              G_PARAM_READWRITE));
1077   gtk_widget_class_install_style_property (klass,
1078                                            g_param_spec_boxed ("cursor-color",
1079                                                                _("Cursor color"),
1080                                                                _("Color with which to draw insertion cursor"),
1081                                                                GDK_TYPE_COLOR,
1082                                                                G_PARAM_READABLE));
1083   gtk_widget_class_install_style_property (klass,
1084                                            g_param_spec_float ("cursor-aspect-ratio",
1085                                                                _("Cursor line aspect ratio"),
1086                                                                _("Aspect ratio with which to draw insertion cursor"),
1087                                                                0.0, 1.0, 0.033,
1088                                                                G_PARAM_READABLE));
1089 }
1090
1091 static void
1092 gtk_widget_set_property (GObject         *object,
1093                          guint            prop_id,
1094                          const GValue    *value,
1095                          GParamSpec      *pspec)
1096 {
1097   GtkWidget *widget = GTK_WIDGET (object);
1098
1099   switch (prop_id)
1100     {
1101       guint32 saved_flags;
1102       
1103     case PROP_NAME:
1104       gtk_widget_set_name (widget, g_value_get_string (value));
1105       break;
1106     case PROP_PARENT:
1107       gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
1108       break;
1109     case PROP_WIDTH_REQUEST:
1110       gtk_widget_set_usize (widget, g_value_get_int (value), -2);
1111       break;
1112     case PROP_HEIGHT_REQUEST:
1113       gtk_widget_set_usize (widget, -2, g_value_get_int (value));
1114       break;
1115     case PROP_VISIBLE:
1116       if (g_value_get_boolean (value))
1117         gtk_widget_show (widget);
1118       else
1119         gtk_widget_hide (widget);
1120       break;
1121     case PROP_SENSITIVE:
1122       gtk_widget_set_sensitive (widget, g_value_get_boolean (value));
1123       break;
1124     case PROP_APP_PAINTABLE:
1125       gtk_widget_set_app_paintable (widget, g_value_get_boolean (value));
1126       break;
1127     case PROP_CAN_FOCUS:
1128       saved_flags = GTK_WIDGET_FLAGS (widget);
1129       if (g_value_get_boolean (value))
1130         GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
1131       else
1132         GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
1133       if (saved_flags != GTK_WIDGET_FLAGS (widget))
1134         gtk_widget_queue_resize (widget);
1135       break;
1136     case PROP_HAS_FOCUS:
1137       if (g_value_get_boolean (value))
1138         gtk_widget_grab_focus (widget);
1139       break;
1140     case PROP_CAN_DEFAULT:
1141       saved_flags = GTK_WIDGET_FLAGS (widget);
1142       if (g_value_get_boolean (value))
1143         GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
1144       else
1145         GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
1146       if (saved_flags != GTK_WIDGET_FLAGS (widget))
1147         gtk_widget_queue_resize (widget);
1148       break;
1149     case PROP_HAS_DEFAULT:
1150       if (g_value_get_boolean (value))
1151         gtk_widget_grab_default (widget);
1152       break;
1153     case PROP_RECEIVES_DEFAULT:
1154       if (g_value_get_boolean (value))
1155         GTK_WIDGET_SET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
1156       else
1157         GTK_WIDGET_UNSET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
1158       break;
1159     case PROP_STYLE:
1160       gtk_widget_set_style (widget, g_value_get_object (value));
1161       break;
1162     case PROP_EVENTS:
1163       if (!GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget))
1164         gtk_widget_set_events (widget, g_value_get_flags (value));
1165       break;
1166     case PROP_EXTENSION_EVENTS:
1167       gtk_widget_set_extension_events (widget, g_value_get_enum (value));
1168       break;
1169     default:
1170       break;
1171     }
1172 }
1173
1174 static void
1175 gtk_widget_get_property (GObject         *object,
1176                          guint            prop_id,
1177                          GValue          *value,
1178                          GParamSpec      *pspec)
1179 {
1180   GtkWidget *widget = GTK_WIDGET (object);
1181   
1182   switch (prop_id)
1183     {
1184       gint *eventp;
1185       GdkExtensionMode *modep;
1186
1187     case PROP_NAME:
1188       if (widget->name)
1189         g_value_set_string (value, widget->name);
1190       else
1191         g_value_set_string (value, "");
1192       break;
1193     case PROP_PARENT:
1194       if (widget->parent)
1195         g_value_set_object (value, widget->parent);
1196       else
1197         g_value_set_object (value, NULL);
1198       break;
1199     case PROP_WIDTH_REQUEST:
1200       {
1201         int w;
1202         gtk_widget_get_size_request (widget, &w, NULL);
1203         g_value_set_int (value, w);
1204       }
1205       break;
1206     case PROP_HEIGHT_REQUEST:
1207       {
1208         int h;
1209         gtk_widget_get_size_request (widget, NULL, &h);
1210         g_value_set_int (value, h);
1211       }
1212       break;
1213     case PROP_VISIBLE:
1214       g_value_set_boolean (value, (GTK_WIDGET_VISIBLE (widget) != FALSE));
1215       break;
1216     case PROP_SENSITIVE:
1217       g_value_set_boolean (value, (GTK_WIDGET_SENSITIVE (widget) != FALSE));
1218       break;
1219     case PROP_APP_PAINTABLE:
1220       g_value_set_boolean (value, (GTK_WIDGET_APP_PAINTABLE (widget) != FALSE));
1221       break;
1222     case PROP_CAN_FOCUS:
1223       g_value_set_boolean (value, (GTK_WIDGET_CAN_FOCUS (widget) != FALSE));
1224       break;
1225     case PROP_HAS_FOCUS:
1226       g_value_set_boolean (value, (GTK_WIDGET_HAS_FOCUS (widget) != FALSE));
1227       break;
1228     case PROP_CAN_DEFAULT:
1229       g_value_set_boolean (value, (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE));
1230       break;
1231     case PROP_HAS_DEFAULT:
1232       g_value_set_boolean (value, (GTK_WIDGET_HAS_DEFAULT (widget) != FALSE));
1233       break;
1234     case PROP_RECEIVES_DEFAULT:
1235       g_value_set_boolean (value, (GTK_WIDGET_RECEIVES_DEFAULT (widget) != FALSE));
1236       break;
1237     case PROP_COMPOSITE_CHILD:
1238       g_value_set_boolean (value, (GTK_WIDGET_COMPOSITE_CHILD (widget) != FALSE));
1239       break;
1240     case PROP_STYLE:
1241       g_value_set_object (value, gtk_widget_get_style (widget));
1242       break;
1243     case PROP_EVENTS:
1244       eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
1245       if (!eventp)
1246         g_value_set_flags (value, 0);
1247       else
1248         g_value_set_flags (value, *eventp);
1249       break;
1250     case PROP_EXTENSION_EVENTS:
1251       modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
1252       if (!modep)
1253         g_value_set_enum (value, 0);
1254       else
1255         g_value_set_enum (value, (GdkExtensionMode) *modep);
1256       break;
1257     default:
1258       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1259       break;
1260     }
1261 }
1262
1263 static void
1264 gtk_widget_init (GtkWidget *widget)
1265 {
1266   GTK_PRIVATE_FLAGS (widget) = PRIVATE_GTK_CHILD_VISIBLE;
1267   widget->state = GTK_STATE_NORMAL;
1268   widget->saved_state = GTK_STATE_NORMAL;
1269   widget->name = NULL;
1270   widget->requisition.width = 0;
1271   widget->requisition.height = 0;
1272   widget->allocation.x = -1;
1273   widget->allocation.y = -1;
1274   widget->allocation.width = 1;
1275   widget->allocation.height = 1;
1276   widget->window = NULL;
1277   widget->parent = NULL;
1278
1279   GTK_WIDGET_SET_FLAGS (widget,
1280                         GTK_SENSITIVE |
1281                         GTK_PARENT_SENSITIVE |
1282                         (composite_child_stack ? GTK_COMPOSITE_CHILD : 0) |
1283                         GTK_DOUBLE_BUFFERED);
1284
1285   GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
1286   GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
1287   GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
1288
1289   widget->style = gtk_widget_get_default_style ();
1290   g_object_ref (widget->style);
1291 }
1292
1293
1294 static void
1295 gtk_widget_dispatch_child_properties_changed (GtkWidget   *widget,
1296                                               guint        n_pspecs,
1297                                               GParamSpec **pspecs)
1298 {
1299   GtkWidget *container = widget->parent;
1300   guint i;
1301
1302   for (i = 0; widget->parent == container && i < n_pspecs; i++)
1303     g_signal_emit (widget, widget_signals[CHILD_NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
1304 }
1305
1306 void
1307 gtk_widget_freeze_child_notify (GtkWidget *widget)
1308 {
1309   g_return_if_fail (GTK_IS_WIDGET (widget));
1310
1311   if (!G_OBJECT (widget)->ref_count)
1312     return;
1313
1314   g_object_ref (widget);
1315   g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
1316   g_object_unref (widget);
1317 }
1318
1319 void
1320 gtk_widget_child_notify (GtkWidget    *widget,
1321                          const gchar  *child_property)
1322 {
1323   GParamSpec *pspec;
1324
1325   g_return_if_fail (GTK_IS_WIDGET (widget));
1326   g_return_if_fail (child_property != NULL);
1327   if (!G_OBJECT (widget)->ref_count || !widget->parent)
1328     return;
1329
1330   g_object_ref (widget);
1331   pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool,
1332                                     child_property,
1333                                     G_OBJECT_TYPE (widget->parent),
1334                                     TRUE);
1335   if (!pspec)
1336     g_warning ("%s: container class `%s' has no child property named `%s'",
1337                G_STRLOC,
1338                G_OBJECT_TYPE_NAME (widget->parent),
1339                child_property);
1340   else
1341     {
1342       GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
1343
1344       g_object_notify_queue_add (G_OBJECT (widget), nqueue, pspec);
1345       g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
1346     }
1347   g_object_unref (widget);
1348 }
1349
1350 /**
1351  * gtk_widget_thaw_child_notify:
1352  * @widget: a #GtkWidget
1353  *
1354  * Reverts the effect of a previous call to gtk_widget_freeze_child_notify().
1355  */ 
1356 void
1357 gtk_widget_thaw_child_notify (GtkWidget *widget)
1358 {
1359   GObjectNotifyQueue *nqueue;
1360
1361   g_return_if_fail (GTK_IS_WIDGET (widget));
1362
1363   if (!G_OBJECT (widget)->ref_count)
1364     return;
1365
1366   g_object_ref (widget);
1367   nqueue = g_object_notify_queue_from_object (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
1368   if (!nqueue || !nqueue->freeze_count)
1369     g_warning (G_STRLOC ": child-property-changed notification for %s(%p) is not frozen",
1370                G_OBJECT_TYPE_NAME (widget), widget);
1371   else
1372     g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
1373   g_object_unref (widget);
1374 }
1375
1376
1377 /**
1378  * gtk_widget_new:
1379  * @type: type ID of the widget to create
1380  * @first_property_name: name of first property to set
1381  * @Varargs: value of first property, followed by more properties, %NULL-terminated
1382  * 
1383  * This is a convenience function for creating a widget and setting
1384  * its properties in one go. For example you might write:
1385  * <literal>gtk_widget_new (GTK_TYPE_LABEL, "label", "Hello World", "xalign",
1386  * 0.0, NULL)</literal> to create a left-aligned label. Equivalent to
1387  * gtk_object_new(), but returns a widget so you don't have to
1388  * cast the object yourself.
1389  * 
1390  * Return value: a new #GtkWidget of type @widget_type
1391  **/
1392 GtkWidget*
1393 gtk_widget_new (GtkType      type,
1394                 const gchar *first_property_name,
1395                 ...)
1396 {
1397   GtkWidget *widget;
1398   va_list var_args;
1399   
1400   g_return_val_if_fail (gtk_type_is_a (type, GTK_TYPE_WIDGET), NULL);
1401   
1402   va_start (var_args, first_property_name);
1403   widget = (GtkWidget *)g_object_new_valist (type, first_property_name, var_args);
1404   va_end (var_args);
1405
1406   return widget;
1407 }
1408
1409 /**
1410  * gtk_widget_set:
1411  * @widget: a #GtkWidget
1412  * @first_property_name: name of first property to set
1413  * @Varargs: value of first property, followed by more properties, %NULL-terminated
1414  * 
1415  * Like gtk_object_set() - there's no reason to use this instead of
1416  * gtk_object_set().
1417  **/
1418 void
1419 gtk_widget_set (GtkWidget   *widget,
1420                 const gchar *first_property_name,
1421                 ...)
1422 {
1423   va_list var_args;
1424
1425   g_return_if_fail (GTK_IS_WIDGET (widget));
1426
1427   va_start (var_args, first_property_name);
1428   g_object_set_valist (G_OBJECT (widget), first_property_name, var_args);
1429   va_end (var_args);
1430 }
1431
1432 static inline void         
1433 gtk_widget_queue_clear_child (GtkWidget *widget)
1434 {
1435   GtkWidget *parent;
1436
1437   parent = widget->parent;
1438   if (parent && GTK_WIDGET_DRAWABLE (parent))
1439     gtk_widget_queue_clear_area (parent,
1440                                  widget->allocation.x,
1441                                  widget->allocation.y,
1442                                  widget->allocation.width,
1443                                  widget->allocation.height);
1444 }
1445
1446 /**
1447  * gtk_widget_unparent:
1448  * @widget: a #GtkWidget
1449  * 
1450  * This function is only for use in widget implementations.
1451  * Should be called by implementations of the remove method
1452  * on #GtkContainer, to dissociate a child from the container.
1453  **/
1454 void
1455 gtk_widget_unparent (GtkWidget *widget)
1456 {
1457   GObjectNotifyQueue *nqueue;
1458   GtkWidget *toplevel;
1459   GtkWidget *old_parent;
1460   
1461   g_return_if_fail (GTK_IS_WIDGET (widget));
1462   if (widget->parent == NULL)
1463     return;
1464   
1465   /* keep this function in sync with gtk_menu_detach()
1466    */
1467
1468   g_object_freeze_notify (G_OBJECT (widget));
1469   nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
1470
1471   /* unset focused and default children properly, this code
1472    * should eventually move into some gtk_window_unparent_branch() or
1473    * similar function.
1474    */
1475   
1476   toplevel = gtk_widget_get_toplevel (widget);
1477   if (GTK_CONTAINER (widget->parent)->focus_child == widget)
1478     {
1479       gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
1480
1481       if (GTK_WIDGET_TOPLEVEL (toplevel))
1482         {
1483           GtkWidget *child;
1484       
1485           child = GTK_WINDOW (toplevel)->focus_widget;
1486           
1487           while (child && child != widget)
1488             child = child->parent;
1489           
1490           if (child == widget)
1491             gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
1492         }
1493     }
1494   if (GTK_WIDGET_TOPLEVEL (toplevel))
1495     {
1496       GtkWidget *child;
1497       
1498       child = GTK_WINDOW (toplevel)->default_widget;
1499       
1500       while (child && child != widget)
1501         child = child->parent;
1502       
1503       if (child == widget)
1504         gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
1505     }
1506
1507   /* If we are unanchoring the child, we save around the toplevel
1508    * to emit hierarchy changed
1509    */
1510   if (GTK_WIDGET_ANCHORED (widget->parent))
1511     g_object_ref (toplevel);
1512   else
1513     toplevel = NULL;
1514
1515   gtk_widget_queue_clear_child (widget);
1516
1517   /* Reset the width and height here, to force reallocation if we
1518    * get added back to a new parent. This won't work if our new
1519    * allocation is smaller than 1x1 and we actually want a size of 1x1...
1520    * (would 0x0 be OK here?)
1521    */
1522   widget->allocation.width = 1;
1523   widget->allocation.height = 1;
1524   
1525   if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_IN_REPARENT (widget))
1526     gtk_widget_unrealize (widget);
1527
1528   /* Removing a widget from a container restores the child visible
1529    * flag to the default state, so it doesn't affect the child
1530    * in the next parent.
1531    */
1532   GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
1533     
1534   old_parent = widget->parent;
1535   widget->parent = NULL;
1536   gtk_widget_set_parent_window (widget, NULL);
1537   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], old_parent);
1538   if (toplevel)
1539     {
1540       _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
1541       g_object_unref (toplevel);
1542     }
1543       
1544   g_object_notify (G_OBJECT (widget), "parent");
1545   g_object_thaw_notify (G_OBJECT (widget));
1546   if (!widget->parent)
1547     g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
1548   g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
1549   gtk_widget_unref (widget);
1550 }
1551
1552 /**
1553  * gtk_widget_destroy:
1554  * @widget: a #GtkWidget
1555  *
1556  * Destroys a widget. Equivalent to gtk_object_destroy(), except that
1557  * you don't have to cast the widget to #GtkObject. When a widget is
1558  * destroyed, it will break any references it holds to other objects.
1559  * If the widget is inside a container, the widget will be removed
1560  * from the container. If the widget is a toplevel (derived from
1561  * #GtkWindow), it will be removed from the list of toplevels, and the
1562  * reference GTK+ holds to it will be removed. Removing a
1563  * widget from its container or the list of toplevels results in the
1564  * widget being finalized, unless you've added additional references
1565  * to the widget with gtk_object_ref().
1566  *
1567  * In most cases, only toplevel widgets (windows) require explicit
1568  * destruction, because when you destroy a toplevel its children will
1569  * be destroyed as well.
1570  * 
1571  **/
1572 void
1573 gtk_widget_destroy (GtkWidget *widget)
1574 {
1575   g_return_if_fail (GTK_IS_WIDGET (widget));
1576
1577   gtk_object_destroy ((GtkObject*) widget);
1578 }
1579
1580 /**
1581  * gtk_widget_destroyed:
1582  * @widget: a #GtkWidget
1583  * @widget_pointer: address of a variable that contains @widget
1584  *
1585  * This function sets *@widget_pointer to %NULL if @widget_pointer !=
1586  * %NULL.  It's intended to be used as a callback connected to the
1587  * "destroy" signal of a widget. You connect gtk_widget_destroyed()
1588  * as a signal handler, and pass the address of your widget variable
1589  * as user data. Then when the widget is destroyed, the variable will
1590  * be set to %NULL. Useful for example to avoid multiple copies
1591  * of the same dialog.
1592  * 
1593  **/
1594 void
1595 gtk_widget_destroyed (GtkWidget      *widget,
1596                       GtkWidget      **widget_pointer)
1597 {
1598   /* Don't make any assumptions about the
1599    *  value of widget!
1600    *  Even check widget_pointer.
1601    */
1602   if (widget_pointer)
1603     *widget_pointer = NULL;
1604 }
1605
1606 /**
1607  * gtk_widget_show:
1608  * @widget: a #GtkWidget
1609  * 
1610  * Flags a widget to be displayed. Any widget that isn't shown will
1611  * not appear on the screen. If you want to show all the widgets in a
1612  * container, it's easier to call gtk_widget_show_all() on the
1613  * container, instead of individually showing the widgets.
1614  *
1615  * Remember that you have to show the containers containing a widget,
1616  * in addition to the widget itself, before it will appear onscreen.
1617  *
1618  * When a toplevel container is shown, it is immediately realized and
1619  * mapped; other shown widgets are realized and mapped when their
1620  * toplevel container is realized and mapped.
1621  * 
1622  **/
1623 void
1624 gtk_widget_show (GtkWidget *widget)
1625 {
1626   g_return_if_fail (GTK_IS_WIDGET (widget));
1627   
1628   if (!GTK_WIDGET_VISIBLE (widget))
1629     {
1630       g_object_ref (G_OBJECT (widget));
1631       if (!GTK_WIDGET_TOPLEVEL (widget))
1632         gtk_widget_queue_resize (widget);
1633       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SHOW]);
1634       g_object_notify (G_OBJECT (widget), "visible");
1635       g_object_unref (G_OBJECT (widget));
1636     }
1637 }
1638
1639 static void
1640 gtk_widget_real_show (GtkWidget *widget)
1641 {
1642   if (!GTK_WIDGET_VISIBLE (widget))
1643     {
1644       GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
1645
1646       if (widget->parent &&
1647           GTK_WIDGET_MAPPED (widget->parent) &&
1648           GTK_WIDGET_CHILD_VISIBLE (widget) &&
1649           !GTK_WIDGET_MAPPED (widget))
1650         gtk_widget_map (widget);
1651     }
1652 }
1653
1654 static void
1655 gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
1656 {
1657   *flag = TRUE;
1658   gtk_signal_disconnect_by_data (GTK_OBJECT (widget), flag);
1659 }
1660
1661 /**
1662  * gtk_widget_show_now:
1663  * @widget: a #GtkWidget
1664  * 
1665  * Shows a widget. If the widget is an unmapped toplevel widget
1666  * (i.e. a #GtkWindow that has not yet been shown), enter the main
1667  * loop and wait for the window to actually be mapped. Be careful;
1668  * because the main loop is running, anything can happen during
1669  * this function.
1670  **/
1671 void
1672 gtk_widget_show_now (GtkWidget *widget)
1673 {
1674   gint flag = FALSE;
1675   
1676   g_return_if_fail (GTK_IS_WIDGET (widget));
1677
1678   /* make sure we will get event */
1679   if (!GTK_WIDGET_MAPPED (widget) &&
1680       GTK_WIDGET_TOPLEVEL (widget))
1681     {
1682       gtk_widget_show (widget);
1683
1684       gtk_signal_connect (GTK_OBJECT (widget), "map_event",
1685                           GTK_SIGNAL_FUNC (gtk_widget_show_map_callback), 
1686                           &flag);
1687
1688       while (!flag)
1689         gtk_main_iteration();
1690     }
1691   else
1692     gtk_widget_show (widget);
1693 }
1694
1695 /**
1696  * gtk_widget_hide:
1697  * @widget: a #GtkWidget
1698  * 
1699  * Reverses the effects of gtk_widget_show(), causing the widget to be
1700  * hidden (invisible to the user).
1701  **/
1702 void
1703 gtk_widget_hide (GtkWidget *widget)
1704 {
1705   g_return_if_fail (GTK_IS_WIDGET (widget));
1706   
1707   if (GTK_WIDGET_VISIBLE (widget))
1708     {
1709       gtk_widget_ref (widget);
1710       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[HIDE]);
1711       if (!GTK_WIDGET_TOPLEVEL (widget))
1712         gtk_widget_queue_resize (widget);
1713       g_object_notify (G_OBJECT (widget), "visible");
1714       gtk_widget_unref (widget);
1715     }
1716 }
1717
1718 static void
1719 gtk_widget_real_hide (GtkWidget *widget)
1720 {
1721   if (GTK_WIDGET_VISIBLE (widget))
1722     {
1723       GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
1724       
1725       if (GTK_WIDGET_MAPPED (widget))
1726         gtk_widget_unmap (widget);
1727     }
1728 }
1729
1730 /**
1731  * gtk_widget_hide_on_delete:
1732  * @widget: a #GtkWidget
1733  * 
1734  * Utility function; intended to be connected to the "delete_event"
1735  * signal on a #GtkWindow. The function calls gtk_widget_hide() on its
1736  * argument, then returns %TRUE. If connected to "delete_event", the
1737  * result is that clicking the close button for a window (on the
1738  * window frame, top right corner usually) will hide but not destroy
1739  * the window. By default, GTK+ destroys windows when "delete_event"
1740  * is received.
1741  * 
1742  * Return value: %TRUE
1743  **/
1744 gboolean
1745 gtk_widget_hide_on_delete (GtkWidget      *widget)
1746 {
1747   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1748   
1749   gtk_widget_hide (widget);
1750   
1751   return TRUE;
1752 }
1753
1754 /**
1755  * gtk_widget_show_all:
1756  * @widget: a #GtkWidget
1757  * 
1758  * Recursively shows a widget, and any child widgets (if the widget is
1759  * a container).
1760  **/
1761 void
1762 gtk_widget_show_all (GtkWidget *widget)
1763 {
1764   GtkWidgetClass *class;
1765
1766   g_return_if_fail (GTK_IS_WIDGET (widget));
1767
1768   class = GTK_WIDGET_GET_CLASS (widget);
1769
1770   if (class->show_all)
1771     class->show_all (widget);
1772 }
1773
1774 /**
1775  * gtk_widget_hide_all:
1776  * @widget: a #GtkWidget
1777  * 
1778  * Recursively hides a widget and any child widgets.
1779  **/
1780 void
1781 gtk_widget_hide_all (GtkWidget *widget)
1782 {
1783   GtkWidgetClass *class;
1784
1785   g_return_if_fail (GTK_IS_WIDGET (widget));
1786
1787   class = GTK_WIDGET_GET_CLASS (widget);
1788
1789   if (class->hide_all)
1790     class->hide_all (widget);
1791 }
1792
1793 /**
1794  * gtk_widget_map:
1795  * @widget: a #GtkWidget
1796  * 
1797  * This function is only for use in widget implementations. Causes
1798  * a widget to be mapped if it isn't already.
1799  * 
1800  **/
1801 void
1802 gtk_widget_map (GtkWidget *widget)
1803 {
1804   g_return_if_fail (GTK_IS_WIDGET (widget));
1805   g_return_if_fail (GTK_WIDGET_VISIBLE (widget));
1806   g_return_if_fail (GTK_WIDGET_CHILD_VISIBLE (widget));
1807   
1808   if (!GTK_WIDGET_MAPPED (widget))
1809     {
1810       if (!GTK_WIDGET_REALIZED (widget))
1811         gtk_widget_realize (widget);
1812
1813       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
1814
1815       if (GTK_WIDGET_NO_WINDOW (widget))
1816         gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
1817     }
1818 }
1819
1820 /**
1821  * gtk_widget_unmap:
1822  * @widget: a #GtkWidget
1823  *
1824  * This function is only for use in widget implementations. Causes
1825  * a widget to be unmapped if it's currently mapped.
1826  * 
1827  **/
1828 void
1829 gtk_widget_unmap (GtkWidget *widget)
1830 {
1831   g_return_if_fail (GTK_IS_WIDGET (widget));
1832   
1833   if (GTK_WIDGET_MAPPED (widget))
1834     {
1835       if (GTK_WIDGET_NO_WINDOW (widget))
1836         gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
1837       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
1838     }
1839 }
1840
1841 /**
1842  * gtk_widget_realize:
1843  * @widget: a #GtkWidget
1844  * 
1845  * Creates the GDK (windowing system) resources associated with a
1846  * widget.  For example, @widget->window will be created when a widget
1847  * is realized.  Normally realization happens implicitly; if you show
1848  * a widget and all its parent containers, then the widget will be
1849  * realized and mapped automatically.
1850  * 
1851  * Realizing a widget requires all
1852  * the widget's parent widgets to be realized; calling
1853  * gtk_widget_realize() realizes the widget's parents in addition to
1854  * @widget itself. If a widget is not yet inside a toplevel window
1855  * when you realize it, bad things will happen.
1856  *
1857  * This function is primarily used in widget implementations, and
1858  * isn't very useful otherwise. Many times when you think you might
1859  * need it, a better approach is to connect to a signal that will be
1860  * called after the widget is realized automatically, such as
1861  * "expose_event". Or simply gtk_signal_connect_after() to the
1862  * "realize" signal.
1863  *  
1864  **/
1865 void
1866 gtk_widget_realize (GtkWidget *widget)
1867 {
1868   gint events;
1869   GdkExtensionMode mode;
1870   GtkWidgetShapeInfo *shape_info;
1871   
1872   g_return_if_fail (GTK_IS_WIDGET (widget));
1873   
1874   if (!GTK_WIDGET_REALIZED (widget))
1875     {
1876       /*
1877         if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
1878           g_message ("gtk_widget_realize(%s)", gtk_type_name (GTK_WIDGET_TYPE (widget)));
1879       */
1880
1881       if (widget->parent == NULL &&
1882           !GTK_WIDGET_TOPLEVEL (widget))
1883         g_warning ("Calling gtk_widget_realize() on a widget that isn't "
1884                    "inside a toplevel window is not going to work very well. "
1885                    "Widgets must be inside a toplevel container before realizing them.");
1886       
1887       if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
1888         gtk_widget_realize (widget->parent);
1889
1890       gtk_widget_ensure_style (widget);
1891       
1892       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);
1893       
1894       if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1895         {
1896           shape_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_shape_info);
1897           gdk_window_shape_combine_mask (widget->window,
1898                                          shape_info->shape_mask,
1899                                          shape_info->offset_x,
1900                                          shape_info->offset_y);
1901         }
1902       
1903       if (!GTK_WIDGET_NO_WINDOW (widget))
1904         {
1905           mode = gtk_widget_get_extension_events (widget);
1906           if (mode != GDK_EXTENSION_EVENTS_NONE)
1907             {
1908               events = gtk_widget_get_events (widget);
1909               gdk_input_set_extension_events (widget->window, events, mode);
1910             }
1911         }
1912       
1913     }
1914 }
1915
1916 /**
1917  * gtk_widget_unrealize:
1918  * @widget: a #GtkWidget
1919  *
1920  * This function is only useful in widget implementations.
1921  * Causes a widget to be unrealized (frees all GDK resources
1922  * associated with the widget, such as @widget->window).
1923  * 
1924  **/
1925 void
1926 gtk_widget_unrealize (GtkWidget *widget)
1927 {
1928   g_return_if_fail (GTK_IS_WIDGET (widget));
1929
1930   if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1931     gtk_widget_shape_combine_mask (widget, NULL, -1, -1);
1932
1933   if (GTK_WIDGET_REALIZED (widget))
1934     {
1935       gtk_widget_ref (widget);
1936       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);
1937       GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
1938       gtk_widget_unref (widget);
1939     }
1940 }
1941
1942 /*****************************************
1943  * Draw queueing.
1944  *****************************************/
1945
1946 /**
1947  * gtk_widget_queue_draw_area:
1948  * @widget: a #GtkWidget
1949  * @x: x coordinate of upper-left corner of rectangle to redraw
1950  * @y: y coordinate of upper-left corner of rectangle to redraw
1951  * @width: width of region to draw
1952  * @height: height of region to draw
1953  *
1954  * Invalidates the rectangular area of @widget defined by @x, @y,
1955  * @width and @height by calling gdk_window_invalidate_rect() on the
1956  * widget's window and all its child windows.  Once the main loop
1957  * becomes idle (after the current batch of events has been processed,
1958  * roughly), the window will receive expose events for the union of
1959  * all regions that have been invalidated.
1960  *
1961  * Normally you would only use this function in widget
1962  * implementations. You might also use it, or
1963  * gdk_window_invalidate_rect() directly, to schedule a redraw of a
1964  * #GtkDrawingArea or some portion thereof.
1965  *
1966  * Frequently you can just call gdk_window_invalidate_rect() or
1967  * gdk_window_invalidate_region() instead of this function. Those
1968  * functions will invalidate only a single window, instead of the
1969  * widget and all its children.
1970  *
1971  * The advantage of adding to the invalidated region compared to
1972  * simply drawing immediately is efficiency; using an invalid region
1973  * ensures that you only have to redraw one time.
1974  * 
1975  **/
1976 void       
1977 gtk_widget_queue_draw_area (GtkWidget *widget,
1978                             gint       x,
1979                             gint       y,
1980                             gint       width,
1981                             gint       height)
1982 {
1983   g_return_if_fail (GTK_IS_WIDGET (widget));
1984
1985   gtk_widget_queue_clear_area (widget, x, y, width, height);
1986 }
1987
1988 /**
1989  * gtk_widget_queue_draw:
1990  * @widget: a #GtkWidget
1991  *
1992  * Equivalent to calling gtk_widget_queue_draw_area() for the
1993  * entire area of a widget.
1994  * 
1995  **/
1996 void       
1997 gtk_widget_queue_draw (GtkWidget *widget)
1998 {
1999   g_return_if_fail (GTK_IS_WIDGET (widget));
2000
2001   gtk_widget_queue_clear (widget);
2002 }
2003
2004 /* Invalidates the given area (allocation-relative-coordinates)
2005  * in all of the widget's windows
2006  */
2007 /**
2008  * gtk_widget_queue_clear_area:
2009  * @widget: a #GtkWidget
2010  * @x: x coordinate of upper-left corner of rectangle to redraw
2011  * @y: y coordinate of upper-left corner of rectangle to redraw
2012  * @width: width of region to draw
2013  * @height: height of region to draw
2014  * 
2015  * DEPRECATED. This function is no longer different from
2016  * gtk_widget_queue_draw_area(), though it once was. Now it just calls
2017  * gtk_widget_queue_draw_area(). Originally
2018  * gtk_widget_queue_clear_area() would force a redraw of the
2019  * background for %GTK_NO_WINDOW widgets, and
2020  * gtk_widget_queue_draw_area() would not. Now both functions ensure
2021  * the background will be redrawn.
2022  * 
2023  **/
2024 void       
2025 gtk_widget_queue_clear_area (GtkWidget *widget,
2026                              gint       x,
2027                              gint       y,
2028                              gint       width,
2029                              gint       height)
2030 {
2031   GdkRectangle invalid_rect;
2032   
2033   g_return_if_fail (GTK_IS_WIDGET (widget));
2034
2035   if (!(widget->window && gdk_window_is_viewable (widget->window)))
2036     return;
2037
2038   /* Find the correct widget */
2039
2040   if (!GTK_WIDGET_NO_WINDOW (widget))
2041     {
2042       if (widget->parent)
2043         {
2044           /* Translate widget relative to window-relative */
2045
2046           gint wx, wy, wwidth, wheight;
2047           
2048           gdk_window_get_position (widget->window, &wx, &wy);
2049           x -= wx - widget->allocation.x;
2050           y -= wy - widget->allocation.y;
2051           
2052           gdk_window_get_size (widget->window, &wwidth, &wheight);
2053
2054           if (x + width <= 0 || y + height <= 0 ||
2055               x >= wwidth || y >= wheight)
2056             return;
2057           
2058           if (x < 0)
2059             {
2060               width += x;  x = 0;
2061             }
2062           if (y < 0)
2063             {
2064               height += y; y = 0;
2065             }
2066           if (x + width > wwidth)
2067             width = wwidth - x;
2068           if (y + height > wheight)
2069             height = wheight - y;
2070         }
2071     }
2072
2073   invalid_rect.x = x;
2074   invalid_rect.y = y;
2075   invalid_rect.width = width;
2076   invalid_rect.height = height;
2077   
2078   gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
2079 }
2080
2081 /**
2082  * gtk_widget_queue_clear:
2083  * @widget: a #GtkWidget
2084  * 
2085  * DEPRECATED. Use gtk_widget_queue_draw() instead.
2086  **/
2087 void       
2088 gtk_widget_queue_clear (GtkWidget *widget)
2089 {
2090   g_return_if_fail (GTK_IS_WIDGET (widget));
2091
2092   if (widget->allocation.width || widget->allocation.height)
2093     {
2094       if (GTK_WIDGET_NO_WINDOW (widget))
2095         gtk_widget_queue_clear_area (widget, widget->allocation.x,
2096                                      widget->allocation.y,
2097                                      widget->allocation.width, 
2098                                      widget->allocation.height);
2099       else
2100         gtk_widget_queue_clear_area (widget, 0, 0, 
2101                                      widget->allocation.width, 
2102                                      widget->allocation.height);
2103     }
2104 }
2105
2106 /**
2107  * gtk_widget_queue_resize:
2108  * @widget: a #GtkWidget
2109  *
2110  * This function is only for use in widget implementations.
2111  * Flags a widget to have its size renegotiated; should
2112  * be called when a widget for some reason has a new size request.
2113  * For example, when you change the text in a #GtkLabel, #GtkLabel
2114  * queues a resize to ensure there's enough space for the new text.
2115  * 
2116  **/
2117 void
2118 gtk_widget_queue_resize (GtkWidget *widget)
2119 {
2120   GdkRegion *region;
2121   
2122   g_return_if_fail (GTK_IS_WIDGET (widget));
2123
2124   if (GTK_WIDGET_REALIZED (widget))
2125     {
2126       region = gdk_region_rectangle (&widget->allocation);
2127       gtk_widget_invalidate_widget_windows (widget, region);
2128       gdk_region_destroy (region);
2129     }
2130       
2131   _gtk_size_group_queue_resize (widget);
2132 }
2133
2134 /**
2135  * gtk_widget_draw:
2136  * @widget: a #GtkWidget
2137  * @area: area to draw
2138  *
2139  * DEPRECATED. In GTK+ 1.2, this function would immediately render the
2140  * region @area of a widget, by invoking the virtual draw method of a
2141  * widget. In GTK+ 2.0, the draw method is gone, and instead
2142  * gtk_widget_draw() simply invalidates the specified region of the
2143  * widget, then updates the invalid region of the widget immediately.
2144  * Usually you don't want to update the region immediately for
2145  * performance reasons, so in general gtk_widget_queue_draw_area() is
2146  * a better choice if you want to draw a region of a widget.
2147  * 
2148  **/
2149 void
2150 gtk_widget_draw (GtkWidget    *widget,
2151                  GdkRectangle *area)
2152 {
2153   g_return_if_fail (GTK_IS_WIDGET (widget));
2154
2155   if (GTK_WIDGET_DRAWABLE (widget))
2156     {
2157       if (area)
2158         gtk_widget_queue_draw_area (widget,
2159                                     area->x, area->y,
2160                                     area->width, area->height);
2161       else
2162         gtk_widget_queue_draw (widget);
2163
2164       gdk_window_process_updates (widget->window, TRUE);
2165     }
2166 }
2167
2168 /**
2169  * gtk_widget_size_request:
2170  * @widget: a #GtkWidget
2171  * @requisition: a #GtkRequisition to be filled in
2172  * 
2173  * This function is typically used when implementing a #GtkContainer
2174  * subclass.  Obtains the preferred size of a widget. The container
2175  * uses this information to arrange its child widgets and decide what
2176  * size allocations to give them with gtk_widget_size_allocate().
2177  *
2178  * You can also call this function from an application, with some
2179  * caveats. Most notably, getting a size request requires the widget
2180  * to be associated with a screen, because font information may be
2181  * needed. Multihead-aware applications should keep this in mind.
2182  *
2183  * Also remember that the size request is not necessarily the size
2184  * a widget will actually be allocated.
2185  *
2186  * See also gtk_widget_get_child_requisition().
2187  **/
2188 void
2189 gtk_widget_size_request (GtkWidget      *widget,
2190                          GtkRequisition *requisition)
2191 {
2192   g_return_if_fail (GTK_IS_WIDGET (widget));
2193
2194 #ifdef G_ENABLE_DEBUG
2195   if (requisition == &widget->requisition)
2196     g_warning ("gtk_widget_size_request() called on child widget with request equal\n to widget->requisition. gtk_widget_set_usize() may not work properly.");
2197 #endif /* G_ENABLE_DEBUG */
2198
2199   _gtk_size_group_compute_requisition (widget, requisition);
2200 }
2201
2202 /**
2203  * gtk_widget_get_child_requisition:
2204  * @widget: a #GtkWidget
2205  * @requisition: a #GtkRequisition to be filled in
2206  * 
2207  * This function is only for use in widget implementations. Obtains
2208  * @widget->requisition, unless someone has forced a particular
2209  * geometry on the widget (e.g. with gtk_widget_set_usize()), in which
2210  * case it returns that geometry instead of the widget's requisition.
2211  *
2212  * This function differs from gtk_widget_size_request() in that
2213  * it retrieves the last size request value from @widget->requisition,
2214  * while gtk_widget_size_request() actually calls the "size_request" method
2215  * on @widget to compute the size request and fill in @widget->requisition,
2216  * and only then returns @widget->requisition.
2217  *
2218  * Because this function does not call the "size_request" method, it
2219  * can only be used when you know that @widget->requisition is
2220  * up-to-date, that is, gtk_widget_size_request() has been called
2221  * since the last time a resize was queued. In general, only container
2222  * implementations have this information; applications should use
2223  * gtk_widget_size_request().
2224  **/
2225 void
2226 gtk_widget_get_child_requisition (GtkWidget      *widget,
2227                                   GtkRequisition *requisition)
2228 {
2229   _gtk_size_group_get_child_requisition (widget, requisition);
2230 }
2231
2232 static gboolean
2233 invalidate_predicate (GdkWindow *window,
2234                       gpointer   data)
2235 {
2236   gpointer user_data;
2237
2238   gdk_window_get_user_data (window, &user_data);
2239
2240   return (user_data == data);
2241 }
2242
2243 /* Invalidate @region in widget->window and all children
2244  * of widget->window owned by widget. @region is in the
2245  * same coordinates as widget->allocation and will be
2246  * modified by this call.
2247  */
2248 static void
2249 gtk_widget_invalidate_widget_windows (GtkWidget *widget,
2250                                       GdkRegion *region)
2251 {
2252   if (!GTK_WIDGET_NO_WINDOW (widget))
2253     {
2254       int x, y;
2255       
2256       gdk_window_get_position (widget->window, &x, &y);
2257       gdk_region_offset (region, -x, -y);
2258     }
2259
2260   gdk_window_invalidate_maybe_recurse (widget->window, region,
2261                                        invalidate_predicate, widget);
2262 }
2263
2264 /**
2265  * gtk_widget_size_allocate:
2266  * @widget: a #GtkWidget
2267  * @allocation: position and size to be allocated to @widget
2268  *
2269  * This function is only used by #GtkContainer subclasses, to assign a size
2270  * and position to their child widgets. 
2271  * 
2272  **/
2273 void
2274 gtk_widget_size_allocate (GtkWidget     *widget,
2275                           GtkAllocation *allocation)
2276 {
2277   GtkWidgetAuxInfo *aux_info;
2278   GdkRectangle real_allocation;
2279   GdkRectangle old_allocation;
2280   gboolean alloc_needed;
2281   gboolean size_changed;
2282   gboolean position_changed;
2283   
2284   g_return_if_fail (GTK_IS_WIDGET (widget));
2285
2286   alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
2287   GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
2288
2289   old_allocation = widget->allocation;
2290   real_allocation = *allocation;
2291   aux_info =_gtk_widget_get_aux_info (widget, FALSE);
2292   
2293   if (aux_info)
2294     {
2295       if (aux_info->x_set)
2296         real_allocation.x = aux_info->x;
2297       if (aux_info->y_set)
2298         real_allocation.y = aux_info->y;
2299     }
2300
2301   if (real_allocation.width < 0 || real_allocation.height < 0)
2302     {
2303       g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
2304                  real_allocation.width,
2305                  real_allocation.height);
2306     }
2307   
2308   real_allocation.width = MAX (real_allocation.width, 1);
2309   real_allocation.height = MAX (real_allocation.height, 1);
2310
2311   size_changed = (old_allocation.width != real_allocation.width ||
2312                   old_allocation.height != real_allocation.height);
2313   position_changed = (old_allocation.x != real_allocation.x ||
2314                       old_allocation.y != real_allocation.y);
2315
2316   if (!alloc_needed && !size_changed && !position_changed)
2317     return;
2318   
2319   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
2320
2321   if (GTK_WIDGET_MAPPED (widget))
2322     {
2323       if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
2324         {
2325           /* Invalidate union(old_allaction,widget->allocation) in widget->window
2326            */
2327           GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
2328           gdk_region_union_with_rect (invalidate, &old_allocation);
2329
2330           gdk_window_invalidate_region (widget->window, invalidate, FALSE);
2331           gdk_region_destroy (invalidate);
2332         }
2333       
2334       if (size_changed)
2335         {
2336           if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
2337             {
2338               /* Invalidate union(old_allaction,widget->allocation) in widget->window and descendents owned by widget
2339                */
2340               GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
2341               gdk_region_union_with_rect (invalidate, &old_allocation);
2342
2343               gtk_widget_invalidate_widget_windows (widget, invalidate);
2344               gdk_region_destroy (invalidate);
2345             }
2346         }
2347     }
2348
2349   if ((size_changed || position_changed) && widget->parent &&
2350       GTK_WIDGET_REALIZED (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
2351     {
2352       GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
2353       gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
2354       gdk_region_destroy (invalidate);
2355     }
2356 }
2357
2358 /**
2359  * gtk_widget_common_ancestor:
2360  * @widget_a: a #GtkWidget
2361  * @widget_b: a #GtkWidget
2362  * 
2363  * Find the common ancestor of @widget_a and @widget_b that
2364  * is closest to the two widgets.
2365  * 
2366  * Return value: the closest common ancestor of @widget_a and
2367  *   @widget_b or %NULL if @widget_a and @widget_b do not
2368  *   share a common ancestor.
2369  **/
2370 static GtkWidget *
2371 gtk_widget_common_ancestor (GtkWidget *widget_a,
2372                             GtkWidget *widget_b)
2373 {
2374   GtkWidget *parent_a;
2375   GtkWidget *parent_b;
2376   gint depth_a = 0;
2377   gint depth_b = 0;
2378
2379   parent_a = widget_a;
2380   while (parent_a->parent)
2381     {
2382       parent_a = parent_a->parent;
2383       depth_a++;
2384     }
2385
2386   parent_b = widget_b;
2387   while (parent_b->parent)
2388     {
2389       parent_b = parent_b->parent;
2390       depth_b++;
2391     }
2392
2393   if (parent_a != parent_b)
2394     return NULL;
2395
2396   while (depth_a > depth_b)
2397     {
2398       widget_a = widget_a->parent;
2399       depth_a--;
2400     }
2401
2402   while (depth_b > depth_a)
2403     {
2404       widget_b = widget_b->parent;
2405       depth_b--;
2406     }
2407
2408   while (widget_a != widget_b)
2409     {
2410       widget_a = widget_a->parent;
2411       widget_b = widget_b->parent;
2412     }
2413
2414   return widget_a;
2415 }
2416
2417 /**
2418  * gtk_widget_translate_coordinates:
2419  * @src_widget:  a #GtkWidget
2420  * @dest_widget: a #GtkWidget
2421  * @src_x: X position relative to @src_widget
2422  * @src_y: Y position relative to @src_widget
2423  * @dest_x: location to store X position relative to @dest_widget
2424  * @dest_y: location to store Y position relative to @dest_widget
2425  * 
2426  * Translate coordinates relative to @src_widget's allocation to coordinates
2427  * relative to @dest_widget's allocations. In order to perform this
2428  * operation, both widgets must be realized, and must share a common
2429  * toplevel.
2430  * 
2431  * Return value: %FALSE if either widget was not realized, or there
2432  *   was no common ancestor. In this case, nothing is stored in
2433  *   *@dest_x and *@dest_y. Otherwise %TRUE.
2434  **/
2435 gboolean
2436 gtk_widget_translate_coordinates (GtkWidget  *src_widget,
2437                                   GtkWidget  *dest_widget,
2438                                   gint        src_x,
2439                                   gint        src_y,
2440                                   gint       *dest_x,
2441                                   gint       *dest_y)
2442 {
2443   GtkWidget *ancestor;
2444   GdkWindow *window;
2445
2446   g_return_val_if_fail (GTK_IS_WIDGET (src_widget), FALSE);
2447   g_return_val_if_fail (GTK_IS_WIDGET (dest_widget), FALSE);
2448
2449   ancestor = gtk_widget_common_ancestor (src_widget, dest_widget);
2450   if (!ancestor || !GTK_WIDGET_REALIZED (src_widget) || !GTK_WIDGET_REALIZED (dest_widget))
2451     return FALSE;
2452
2453   /* Translate from allocation relative to window relative */
2454   if (!GTK_WIDGET_NO_WINDOW (src_widget) && src_widget->parent)
2455     {
2456       gint wx, wy;
2457       gdk_window_get_position (src_widget->window, &wx, &wy);
2458
2459       src_x -= wx - src_widget->allocation.x;
2460       src_y -= wy - src_widget->allocation.y;
2461     }
2462   else
2463     {
2464       src_x += src_widget->allocation.x;
2465       src_y += src_widget->allocation.y;
2466     }
2467
2468   /* Translate to the common ancestor */
2469   window = src_widget->window;
2470   while (window != ancestor->window)
2471     {
2472       gint dx, dy;
2473       
2474       gdk_window_get_position (window, &dx, &dy);
2475       
2476       src_x += dx;
2477       src_y += dy;
2478       
2479       window = gdk_window_get_parent (window);
2480     }
2481
2482   /* And back */
2483   window = dest_widget->window;
2484   while (window != ancestor->window)
2485     {
2486       gint dx, dy;
2487       
2488       gdk_window_get_position (window, &dx, &dy);
2489       
2490       src_x -= dx;
2491       src_y -= dy;
2492       
2493       window = gdk_window_get_parent (window);
2494     }
2495
2496   /* Translate from window relative to allocation relative */
2497   if (!GTK_WIDGET_NO_WINDOW (dest_widget) && dest_widget->parent)
2498     {
2499       gint wx, wy;
2500       gdk_window_get_position (dest_widget->window, &wx, &wy);
2501
2502       src_x += wx - dest_widget->allocation.x;
2503       src_y += wy - dest_widget->allocation.y;
2504     }
2505   else
2506     {
2507       src_x -= dest_widget->allocation.x;
2508       src_y -= dest_widget->allocation.y;
2509     }
2510
2511   if (dest_x)
2512     *dest_x = src_x;
2513   if (dest_y)
2514     *dest_y = src_y;
2515
2516   return TRUE;
2517 }
2518
2519 static void
2520 gtk_widget_real_size_allocate (GtkWidget     *widget,
2521                                GtkAllocation *allocation)
2522 {
2523   widget->allocation = *allocation;
2524   
2525   if (GTK_WIDGET_REALIZED (widget) &&
2526       !GTK_WIDGET_NO_WINDOW (widget))
2527      {
2528         gdk_window_move_resize (widget->window,
2529                                 allocation->x, allocation->y,
2530                                 allocation->width, allocation->height);
2531      }
2532 }
2533
2534 typedef struct {
2535   GClosure   closure;
2536   guint      signal_id;
2537 } AccelClosure;
2538
2539 static void
2540 closure_accel_activate (GClosure     *closure,
2541                         GValue       *return_value,
2542                         guint         n_param_values,
2543                         const GValue *param_values,
2544                         gpointer      invocation_hint,
2545                         gpointer      marshal_data)
2546 {
2547   AccelClosure *aclosure = (AccelClosure*) closure;
2548
2549   if (GTK_WIDGET_IS_SENSITIVE (closure->data))
2550     g_signal_emit (closure->data, aclosure->signal_id, 0);
2551
2552   /* we handled the accelerator */
2553   g_value_set_boolean (return_value, TRUE);
2554 }
2555
2556 static void
2557 closures_destroy (gpointer data)
2558 {
2559   GSList *slist, *closures = data;
2560
2561   for (slist = closures; slist; slist = slist->next)
2562     {
2563       g_closure_invalidate (slist->data);
2564       g_closure_unref (slist->data);
2565     }
2566   g_slist_free (closures);
2567 }
2568
2569 static GClosure*
2570 widget_new_accel_closure (GtkWidget *widget,
2571                           guint      signal_id)
2572 {
2573   AccelClosure *aclosure;
2574   GClosure *closure = NULL;
2575   GSList *slist, *closures;
2576
2577   closures = g_object_steal_qdata (G_OBJECT (widget), quark_accel_closures);
2578   for (slist = closures; slist; slist = slist->next)
2579     if (!gtk_accel_group_from_accel_closure (slist->data))
2580       {
2581         /* reuse this closure */
2582         closure = slist->data;
2583         break;
2584       }
2585   if (!closure)
2586     {
2587       closure = g_closure_new_object (sizeof (AccelClosure), G_OBJECT (widget));
2588       closures = g_slist_prepend (closures, g_closure_ref (closure));
2589       g_closure_sink (closure);
2590       g_closure_set_marshal (closure, closure_accel_activate);
2591     }
2592   g_object_set_qdata_full (G_OBJECT (widget), quark_accel_closures, closures, closures_destroy);
2593   
2594   aclosure = (AccelClosure*) closure;
2595   g_assert (closure->data == widget);
2596   g_assert (closure->marshal == closure_accel_activate);
2597   aclosure->signal_id = signal_id;
2598
2599   return closure;
2600 }
2601
2602 /**
2603  * gtk_widget_add_accelerator
2604  * @widget:       widget to install an accelerator on
2605  * @accel_signal: widget signal to emit on accelerator activation
2606  * @accel_group:  accel group for this widget, added to its toplevel
2607  * @accel_key:    GDK keyval of the accelerator
2608  * @accel_mods:   modifier key combination of the accelerator
2609  * @accel_flags:  flag accelerators, e.g. %GTK_ACCEL_VISIBLE
2610  *
2611  * Installs an accelerator for this @widget in @accel_group that causes
2612  * @accel_signal to be emitted if the accelerator is activated.
2613  * The @accel_group needs to be added to the widget's toplevel via
2614  * gtk_window_add_accel_group(), and the signal must be of type %G_RUN_ACTION.
2615  * Accelerators added through this function are not user changeable during
2616  * runtime. If you want to support accelerators that can be changed by the
2617  * user, use gtk_accel_map_add_entry() and gtk_widget_set_accel_path() or
2618  * gtk_menu_item_set_accel_path() instead.
2619  */
2620 void
2621 gtk_widget_add_accelerator (GtkWidget      *widget,
2622                             const gchar    *accel_signal,
2623                             GtkAccelGroup  *accel_group,
2624                             guint           accel_key,
2625                             GdkModifierType accel_mods,
2626                             GtkAccelFlags   accel_flags)
2627 {
2628   GClosure *closure;
2629   GSignalQuery query;
2630
2631   g_return_if_fail (GTK_IS_WIDGET (widget));
2632   g_return_if_fail (accel_signal != NULL);
2633   g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2634
2635   g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query);
2636   if (!query.signal_id ||
2637       !(query.signal_flags & G_SIGNAL_ACTION) ||
2638       query.return_type != G_TYPE_NONE ||
2639       query.n_params)
2640     {
2641       /* hmm, should be elaborate enough */
2642       g_warning (G_STRLOC ": widget `%s' has no activatable signal \"%s\" without arguments",
2643                  G_OBJECT_TYPE_NAME (widget), accel_signal);
2644       return;
2645     }
2646
2647   closure = widget_new_accel_closure (widget, query.signal_id);
2648
2649   g_object_ref (widget);
2650
2651   /* install the accelerator. since we don't map this onto an accel_path,
2652    * the accelerator will automatically be locked.
2653    */
2654   gtk_accel_group_connect (accel_group,
2655                            accel_key,
2656                            accel_mods,
2657                            accel_flags | GTK_ACCEL_LOCKED,
2658                            closure);
2659
2660   g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
2661
2662   g_object_unref (widget);
2663 }
2664
2665 /**
2666  * gtk_widget_remove_accelerator:
2667  * @widget:       widget to install an accelerator on
2668  * @accel_group:  accel group for this widget
2669  * @accel_key:    GDK keyval of the accelerator
2670  * @accel_mods:   modifier key combination of the accelerator
2671  * @returns:      whether an accelerator was installed and could be removed
2672  *
2673  * Removes an accelerator from @widget, previously installed with
2674  * gtk_widget_add_accelerator().
2675  */
2676 gboolean
2677 gtk_widget_remove_accelerator (GtkWidget      *widget,
2678                                GtkAccelGroup  *accel_group,
2679                                guint           accel_key,
2680                                GdkModifierType accel_mods)
2681 {
2682   GtkAccelGroupEntry *ag_entry;
2683   GList *slist, *clist;
2684   guint n;
2685   
2686   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2687   g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
2688
2689   ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
2690   clist = gtk_widget_list_accel_closures (widget);
2691   for (slist = clist; slist; slist = slist->next)
2692     {
2693       guint i;
2694
2695       for (i = 0; i < n; i++)
2696         if (slist->data == (gpointer) ag_entry[i].closure)
2697           {
2698             gboolean is_removed = gtk_accel_group_disconnect (accel_group, slist->data);
2699
2700             g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
2701
2702             g_list_free (clist);
2703
2704             return is_removed;
2705           }
2706     }
2707   g_list_free (clist);
2708
2709   g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
2710              accel_key, accel_mods, accel_group,
2711              G_OBJECT_TYPE_NAME (widget), widget);
2712
2713   return FALSE;
2714 }
2715
2716 /**
2717  * gtk_widget_list_accel_closures
2718  * @widget:  widget to list accelerator closures for
2719  * @returns: a newly allocated #GList of closures
2720  *
2721  * Lists the closures used by @widget for accelerator group connections
2722  * with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
2723  * The closures can be used to monitor accelerator changes on @widget,
2724  * by connecting to the ::accel_changed signal of the #GtkAccelGroup of a 
2725  * closure which can be found out with gtk_accel_group_from_accel_closure().
2726  */
2727 GList*
2728 gtk_widget_list_accel_closures (GtkWidget *widget)
2729 {
2730   GSList *slist;
2731   GList *clist = NULL;
2732
2733   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2734
2735   for (slist = g_object_get_qdata (G_OBJECT (widget), quark_accel_closures); slist; slist = slist->next)
2736     if (gtk_accel_group_from_accel_closure (slist->data))
2737       clist = g_list_prepend (clist, slist->data);
2738   return clist;
2739 }
2740
2741 typedef struct {
2742   GQuark         path_quark;
2743   GtkWidget     *widget;
2744   GtkAccelGroup *accel_group;
2745   GClosure      *closure;
2746 } AccelPath;
2747
2748 static void
2749 destroy_accel_path (gpointer data)
2750 {
2751   AccelPath *apath = data;
2752
2753   gtk_accel_group_disconnect (apath->accel_group, apath->closure);
2754
2755   /* closures_destroy takes care of unrefing the closure */
2756   g_object_unref (apath->accel_group);
2757   
2758   g_free (apath);
2759 }
2760
2761
2762 /**
2763  * gtk_widget_set_accel_path:
2764  * @widget: a #GtkWidget
2765  * @accel_path: path used to look up the the accelerator
2766  * @accel_group: a #GtkAccelGroup.
2767  * 
2768  * Given an accelerator group, @accel_group, and an accelerator path,
2769  * @accel_path, sets up an accelerator in @accel_group so whenever the
2770  * key binding that is defined for @accel_path is pressed, @widget
2771  * will be activated.  This removes any accelerators (for any
2772  * accelerator group) installed by previous calls to
2773  * gtk_widget_set_accel_path(). Associating accelerators with
2774  * paths allows them to be modified by the user and the modifications
2775  * to be saved for future use. (See gtk_accel_map_save().)
2776  *
2777  * This function is a low level function that would most likely
2778  * be used by a menu creation system like #GtkItemFactory. If you
2779  * use #GtkItemFactory, setting up accelerator paths will be done
2780  * automatically.
2781  *
2782  * Even when you you aren't using #GtkItemFactory, if you only want to
2783  * set up accelerators on menu items gtk_menu_item_set_accel_path()
2784  * provides a somewhat more convenient interface.
2785  **/
2786 void
2787 gtk_widget_set_accel_path (GtkWidget     *widget,
2788                            const gchar   *accel_path,
2789                            GtkAccelGroup *accel_group)
2790 {
2791   AccelPath *apath;
2792
2793   g_return_if_fail (GTK_IS_WIDGET (widget));
2794   g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
2795
2796   if (accel_path)
2797     {
2798       g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2799       g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
2800
2801       gtk_accel_map_add_entry (accel_path, 0, 0);
2802       apath = g_new (AccelPath, 1);
2803       apath->widget = widget;
2804       apath->accel_group = g_object_ref (accel_group);
2805       apath->path_quark = g_quark_from_string (accel_path);
2806       apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
2807     }
2808   else
2809     apath = NULL;
2810
2811   /* also removes possible old settings */
2812   g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
2813
2814   if (apath)
2815     gtk_accel_group_connect_by_path (apath->accel_group, g_quark_to_string (apath->path_quark), apath->closure);
2816
2817   g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
2818 }
2819
2820 const gchar*
2821 _gtk_widget_get_accel_path (GtkWidget *widget)
2822 {
2823   AccelPath *apath;
2824
2825   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2826
2827   apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
2828   return apath ? g_quark_to_string (apath->path_quark) : NULL;
2829 }
2830
2831 gboolean
2832 gtk_widget_mnemonic_activate (GtkWidget *widget,
2833                               gboolean   group_cycling)
2834 {
2835   gboolean handled;
2836   
2837   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2838
2839   group_cycling = group_cycling != FALSE;
2840   if (!GTK_WIDGET_IS_SENSITIVE (widget))
2841     handled = TRUE;
2842   else
2843     gtk_signal_emit (GTK_OBJECT (widget),
2844                      widget_signals[MNEMONIC_ACTIVATE],
2845                      group_cycling,
2846                      &handled);
2847   return handled;
2848 }
2849
2850 static gboolean
2851 gtk_widget_real_mnemonic_activate (GtkWidget *widget,
2852                                    gboolean   group_cycling)
2853 {
2854   if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
2855     gtk_widget_activate (widget);
2856   else if (GTK_WIDGET_CAN_FOCUS (widget))
2857     gtk_widget_grab_focus (widget);
2858   else
2859     {
2860       g_warning ("widget `%s' isn't suitable for mnemonic activation",
2861                  G_OBJECT_TYPE_NAME (widget));
2862       gdk_beep ();
2863     }
2864   return TRUE;
2865 }
2866
2867 static gboolean
2868 gtk_widget_real_key_press_event (GtkWidget         *widget,
2869                                  GdkEventKey       *event)
2870 {
2871   return _gtk_bindings_activate_event (GTK_OBJECT (widget), event);
2872 }
2873
2874 static gboolean
2875 gtk_widget_real_key_release_event (GtkWidget         *widget,
2876                                    GdkEventKey       *event)
2877 {
2878   return _gtk_bindings_activate_event (GTK_OBJECT (widget), event);
2879 }
2880
2881 static gboolean
2882 gtk_widget_real_focus_in_event (GtkWidget     *widget,
2883                                 GdkEventFocus *event)
2884 {
2885   gtk_widget_queue_draw (widget);
2886
2887   return FALSE;
2888 }
2889
2890 static gboolean
2891 gtk_widget_real_focus_out_event (GtkWidget     *widget,
2892                                  GdkEventFocus *event)
2893 {
2894   gtk_widget_queue_draw (widget);
2895
2896   return FALSE;
2897 }
2898
2899 #define WIDGET_REALIZED_FOR_EVENT(widget, event) \
2900      (event->type == GDK_FOCUS_CHANGE || GTK_WIDGET_REALIZED(widget))
2901
2902 /**
2903  * gtk_widget_event:
2904  * @widget: a #GtkWidget
2905  * @event: a #GdkEvent
2906  * 
2907  * Rarely-used function. This function is used to emit
2908  * the event signals on a widget (those signals should never
2909  * be emitted without using this function to do so).
2910  * If you want to synthesize an event though, don't use this function;
2911  * instead, use gtk_main_do_event() so the event will behave as if
2912  * it were in the event queue. Don't synthesize expose events; instead,
2913  * use gdk_window_invalidate_rect() to invalidate a region of the
2914  * window.
2915  * 
2916  * Return value: return from the event signal emission (%TRUE if the event was handled)
2917  **/
2918 gboolean
2919 gtk_widget_event (GtkWidget *widget,
2920                   GdkEvent  *event)
2921 {
2922   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
2923   g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
2924
2925   if (event->type == GDK_EXPOSE)
2926     {
2927       g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
2928                  "the same effect, call gdk_window_invalidate_rect/region(), "
2929                  "followed by gdk_window_process_updates().");
2930       return TRUE;
2931     }
2932   
2933   return gtk_widget_event_internal (widget, event);
2934 }
2935
2936
2937 /**
2938  * gtk_widget_send_expose:
2939  * @widget: a #GtkWidget
2940  * @event: a expose #GdkEvent
2941  * 
2942  * Very rarely-used function. This function is used to emit
2943  * an expose event signals on a widget. This function is not
2944  * normally used directly. The only time it is used is when
2945  * propagating an expose event to a child %NO_WINDOW widget, and
2946  * that is normally done using gtk_container_propagate_expose().
2947  *
2948  * If you want to force an area of a window to be redrawn, 
2949  * use gdk_window_invalidate_rect() or gdk_window_invalidate_region().
2950  * To cause the redraw to be done immediately, follow that call
2951  * with a call to gdk_window_process_updates().
2952  * 
2953  * Return value: return from the event signal emission (%TRUE if the event was handled)
2954  **/
2955 gint
2956 gtk_widget_send_expose (GtkWidget *widget,
2957                         GdkEvent  *event)
2958 {
2959   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
2960   g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), TRUE);
2961   g_return_val_if_fail (event != NULL, TRUE);
2962   g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
2963
2964   if (event->type != GDK_EXPOSE)
2965     return TRUE;
2966   
2967   return gtk_widget_event_internal (widget, event);
2968 }
2969
2970 static gint
2971 gtk_widget_event_internal (GtkWidget *widget,
2972                            GdkEvent  *event)
2973 {
2974   gboolean return_val = FALSE;
2975
2976   gtk_widget_ref (widget);
2977
2978   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event, &return_val);
2979   return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
2980   if (!return_val)
2981     {
2982       gint signal_num;
2983
2984       switch (event->type)
2985         {
2986         case GDK_NOTHING:
2987           signal_num = -1;
2988           break;
2989         case GDK_BUTTON_PRESS:
2990         case GDK_2BUTTON_PRESS:
2991         case GDK_3BUTTON_PRESS:
2992           signal_num = BUTTON_PRESS_EVENT;
2993           break;
2994         case GDK_SCROLL:
2995           signal_num = SCROLL_EVENT;
2996           break;
2997         case GDK_BUTTON_RELEASE:
2998           signal_num = BUTTON_RELEASE_EVENT;
2999           break;
3000         case GDK_MOTION_NOTIFY:
3001           signal_num = MOTION_NOTIFY_EVENT;
3002           break;
3003         case GDK_DELETE:
3004           signal_num = DELETE_EVENT;
3005           break;
3006         case GDK_DESTROY:
3007           signal_num = DESTROY_EVENT;
3008           break;
3009         case GDK_KEY_PRESS:
3010           signal_num = KEY_PRESS_EVENT;
3011           break;
3012         case GDK_KEY_RELEASE:
3013           signal_num = KEY_RELEASE_EVENT;
3014           break;
3015         case GDK_ENTER_NOTIFY:
3016           signal_num = ENTER_NOTIFY_EVENT;
3017           break;
3018         case GDK_LEAVE_NOTIFY:
3019           signal_num = LEAVE_NOTIFY_EVENT;
3020           break;
3021         case GDK_FOCUS_CHANGE:
3022           signal_num = event->focus_change.in ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
3023           break;
3024         case GDK_CONFIGURE:
3025           signal_num = CONFIGURE_EVENT;
3026           break;
3027         case GDK_MAP:
3028           signal_num = MAP_EVENT;
3029           break;
3030         case GDK_UNMAP:
3031           signal_num = UNMAP_EVENT;
3032           break;
3033         case GDK_WINDOW_STATE:
3034           signal_num = WINDOW_STATE_EVENT;
3035           break;
3036         case GDK_PROPERTY_NOTIFY:
3037           signal_num = PROPERTY_NOTIFY_EVENT;
3038           break;
3039         case GDK_SELECTION_CLEAR:
3040           signal_num = SELECTION_CLEAR_EVENT;
3041           break;
3042         case GDK_SELECTION_REQUEST:
3043           signal_num = SELECTION_REQUEST_EVENT;
3044           break;
3045         case GDK_SELECTION_NOTIFY:
3046           signal_num = SELECTION_NOTIFY_EVENT;
3047           break;
3048         case GDK_PROXIMITY_IN:
3049           signal_num = PROXIMITY_IN_EVENT;
3050           break;
3051         case GDK_PROXIMITY_OUT:
3052           signal_num = PROXIMITY_OUT_EVENT;
3053           break;
3054         case GDK_NO_EXPOSE:
3055           signal_num = NO_EXPOSE_EVENT;
3056           break;
3057         case GDK_CLIENT_EVENT:
3058           signal_num = CLIENT_EVENT;
3059           break;
3060         case GDK_EXPOSE:
3061           signal_num = EXPOSE_EVENT;
3062           break;
3063         case GDK_VISIBILITY_NOTIFY:
3064           signal_num = VISIBILITY_NOTIFY_EVENT;
3065           break;
3066         default:
3067           g_warning ("gtk_widget_event(): unhandled event type: %d", event->type);
3068           signal_num = -1;
3069           break;
3070         }
3071       if (signal_num != -1)
3072         gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val);
3073     }
3074   if (WIDGET_REALIZED_FOR_EVENT (widget, event))
3075     gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT_AFTER], event);
3076   else
3077     return_val = TRUE;
3078
3079   gtk_widget_unref (widget);
3080
3081   return return_val;
3082 }
3083
3084 /**
3085  * gtk_widget_activate:
3086  * @widget: a #GtkWidget that's activatable
3087  * 
3088  * For widgets that can be "activated" (buttons, menu items, etc.)
3089  * this function activates them. Activation is what happens when you
3090  * press Enter on a widget during key navigation; clicking a button,
3091  * selecting a menu item, etc. If @widget isn't activatable,
3092  * the function returns %FALSE.
3093  * 
3094  * Return value: %TRUE if the widget was activatable
3095  **/
3096 gboolean
3097 gtk_widget_activate (GtkWidget *widget)
3098 {
3099   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3100   
3101   if (WIDGET_CLASS (widget)->activate_signal)
3102     {
3103       /* FIXME: we should eventually check the signals signature here */
3104       gtk_signal_emit (GTK_OBJECT (widget), WIDGET_CLASS (widget)->activate_signal);
3105
3106       return TRUE;
3107     }
3108   else
3109     return FALSE;
3110 }
3111
3112 /**
3113  * gtk_widget_set_scroll_adjustments:
3114  * @widget: a #GtkWidget
3115  * @hadjustment: an adjustment for horizontal scrolling, or %NULL
3116  * @vadjustment: an adjustment for vertical scrolling, or %NULL
3117  *
3118  * For widgets that support scrolling, sets the scroll adjustments and
3119  * returns %TRUE.  For widgets that don't support scrolling, does
3120  * nothing and returns %FALSE. Widgets that don't support scrolling
3121  * can be scrolled by placing them in a #GtkViewport, which does
3122  * support scrolling.
3123  * 
3124  * Return value: %TRUE if the widget supports scrolling
3125  **/
3126 gboolean
3127 gtk_widget_set_scroll_adjustments (GtkWidget     *widget,
3128                                    GtkAdjustment *hadjustment,
3129                                    GtkAdjustment *vadjustment)
3130 {
3131   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3132   if (hadjustment)
3133     g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), FALSE);
3134   if (vadjustment)
3135     g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), FALSE);
3136
3137   if (WIDGET_CLASS (widget)->set_scroll_adjustments_signal)
3138     {
3139       /* FIXME: we should eventually check the signals signature here */
3140       gtk_signal_emit (GTK_OBJECT (widget),
3141                        WIDGET_CLASS (widget)->set_scroll_adjustments_signal,
3142                        hadjustment, vadjustment);
3143       return TRUE;
3144     }
3145   else
3146     return FALSE;
3147 }
3148
3149 /*****************************************
3150  * gtk_widget_reparent_container_child:
3151  *   assistent function to gtk_widget_reparent
3152  *
3153  *   arguments:
3154  *
3155  *   results:
3156  *****************************************/
3157
3158 static void
3159 gtk_widget_reparent_container_child (GtkWidget *widget,
3160                                      gpointer   client_data)
3161 {
3162   g_return_if_fail (client_data != NULL);
3163   
3164   if (GTK_WIDGET_NO_WINDOW (widget))
3165     {
3166       if (widget->window)
3167         gdk_window_unref (widget->window);
3168       widget->window = (GdkWindow*) client_data;
3169       if (widget->window)
3170         gdk_window_ref (widget->window);
3171
3172       if (GTK_IS_CONTAINER (widget))
3173         gtk_container_forall (GTK_CONTAINER (widget),
3174                               gtk_widget_reparent_container_child,
3175                               client_data);
3176     }
3177   else
3178     gdk_window_reparent (widget->window, 
3179                          (GdkWindow*) client_data, 0, 0);
3180 }
3181
3182 /**
3183  * gtk_widget_reparent:
3184  * @widget: a #GtkWidget
3185  * @new_parent: a #GtkContainer to move the widget into
3186  *
3187  * Moves a widget from one #GtkContainer to another, handling reference
3188  * count issues to avoid destroying the widget.
3189  * 
3190  **/
3191 void
3192 gtk_widget_reparent (GtkWidget *widget,
3193                      GtkWidget *new_parent)
3194 {
3195   g_return_if_fail (GTK_IS_WIDGET (widget));
3196   g_return_if_fail (GTK_IS_CONTAINER (new_parent));
3197   g_return_if_fail (widget->parent != NULL);
3198   
3199   if (widget->parent != new_parent)
3200     {
3201       /* First try to see if we can get away without unrealizing
3202        * the widget as we reparent it. if so we set a flag so
3203        * that gtk_widget_unparent doesn't unrealize widget
3204        */
3205       if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
3206         GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
3207       
3208       gtk_widget_ref (widget);
3209       gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
3210       gtk_container_add (GTK_CONTAINER (new_parent), widget);
3211       gtk_widget_unref (widget);
3212       
3213       if (GTK_WIDGET_IN_REPARENT (widget))
3214         {
3215           GTK_PRIVATE_UNSET_FLAG (widget, GTK_IN_REPARENT);
3216           
3217           gtk_widget_reparent_container_child (widget,
3218                                                gtk_widget_get_parent_window (widget));
3219         }
3220
3221       g_object_notify (G_OBJECT (widget), "parent");
3222     }
3223 }
3224
3225 /**
3226  * gtk_widget_intersect:
3227  * @widget: a #GtkWidget
3228  * @area: a rectangle
3229  * @intersection: rectangle to store intersection of @widget and @area
3230  * 
3231  * Computes the intersection of a @widget's area and @area, storing
3232  * the intersection in @intersection, and returns %TRUE if there was
3233  * an intersection.  @intersection may be %NULL if you're only
3234  * interested in whether there was an intersection.
3235  * 
3236  * Return value: %TRUE if there was an intersection
3237  **/
3238 gboolean
3239 gtk_widget_intersect (GtkWidget    *widget,
3240                       GdkRectangle *area,
3241                       GdkRectangle *intersection)
3242 {
3243   GdkRectangle *dest;
3244   GdkRectangle tmp;
3245   gint return_val;
3246   
3247   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3248   g_return_val_if_fail (area != NULL, FALSE);
3249   
3250   if (intersection)
3251     dest = intersection;
3252   else
3253     dest = &tmp;
3254   
3255   return_val = gdk_rectangle_intersect (&widget->allocation, area, dest);
3256   
3257   if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
3258     {
3259       intersection->x -= widget->allocation.x;
3260       intersection->y -= widget->allocation.y;
3261     }
3262   
3263   return return_val;
3264 }
3265
3266 /**
3267  * gtk_widget_region_intersect:
3268  * @widget: a #GtkWidget
3269  * @region: a #GdkRegion, in the same coordinate system as 
3270  *          @widget->allocation. That is, relative to @widget->window
3271  *          for %NO_WINDOW widgets; relative to the parent window
3272  *          of @widget->window for widgets with their own window.
3273  * @returns: A newly allocated region holding the intersection of @widget
3274  *           and @region. The coordinates of the return value are
3275  *           relative to @widget->window for %NO_WINDOW widgets, and
3276  *           relative to the parent window of @widget->window for
3277  *           widgets with their own window.
3278  * 
3279  * Computes the intersection of a @widget's area and @region, returning
3280  * the intersection. The result may be empty, use gdk_region_empty() to
3281  * check.
3282  **/
3283 GdkRegion *
3284 gtk_widget_region_intersect (GtkWidget *widget,
3285                              GdkRegion *region)
3286 {
3287   GdkRegion *dest;
3288   
3289   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3290   g_return_val_if_fail (region != NULL, NULL);
3291   
3292   dest = gdk_region_rectangle (&widget->allocation);
3293  
3294   gdk_region_intersect (dest, region);
3295
3296   return dest;
3297 }
3298
3299 /**
3300  * gtk_widget_grab_focus:
3301  * @widget: a #GtkWidget
3302  * 
3303  * Causes @widget to have the keyboard focus for the #GtkWindow it's
3304  * inside. @widget must be a focusable widget, such as a #GtkEntry;
3305  * something like #GtkFrame won't work. (More precisely, it must have the
3306  * %GTK_CAN_FOCUS flag set.)
3307  * 
3308  **/
3309 void
3310 gtk_widget_grab_focus (GtkWidget *widget)
3311 {
3312   g_return_if_fail (GTK_IS_WIDGET (widget));
3313
3314   if (!GTK_WIDGET_IS_SENSITIVE (widget))
3315     return;
3316   
3317   g_object_ref (G_OBJECT (widget));
3318   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[GRAB_FOCUS]);
3319   g_object_notify (G_OBJECT (widget), "has_focus");
3320   g_object_unref (G_OBJECT (widget));
3321 }
3322
3323 static void
3324 reset_focus_recurse (GtkWidget *widget,
3325                      gpointer   data)
3326 {
3327   if (GTK_IS_CONTAINER (widget))
3328     {
3329       GtkContainer *container;
3330
3331       container = GTK_CONTAINER (widget);
3332       gtk_container_set_focus_child (container, NULL);
3333
3334       gtk_container_foreach (container,
3335                              reset_focus_recurse,
3336                              NULL);
3337     }
3338 }
3339
3340 static void
3341 gtk_widget_real_grab_focus (GtkWidget *focus_widget)
3342 {
3343   if (GTK_WIDGET_CAN_FOCUS (focus_widget))
3344     {
3345       GtkWidget *toplevel;
3346       GtkWidget *widget;
3347       
3348       /* clear the current focus setting, break if the current widget
3349        * is the focus widget's parent, since containers above that will
3350        * be set by the next loop.
3351        */
3352       toplevel = gtk_widget_get_toplevel (focus_widget);
3353       if (GTK_WIDGET_TOPLEVEL (toplevel))
3354         {
3355           widget = GTK_WINDOW (toplevel)->focus_widget;
3356           
3357           if (widget == focus_widget)
3358             {
3359               /* We call _gtk_window_internal_set_focus() here so that the
3360                * toplevel window can request the focus if necessary.
3361                * This is needed when the toplevel is a GtkPlug
3362                */
3363               if (!GTK_WIDGET_HAS_FOCUS (widget))
3364                 _gtk_window_internal_set_focus (GTK_WINDOW (toplevel), focus_widget);
3365
3366               return;
3367             }
3368           
3369           if (widget)
3370             {
3371               while (widget->parent && widget->parent != focus_widget->parent)
3372                 {
3373                   widget = widget->parent;
3374                   gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
3375                 }
3376             }
3377         }
3378       else if (toplevel != focus_widget)
3379         {
3380           /* gtk_widget_grab_focus() operates on a tree without window...
3381            * actually, this is very questionable behaviour.
3382            */
3383           
3384           gtk_container_foreach (GTK_CONTAINER (toplevel),
3385                                  reset_focus_recurse,
3386                                  NULL);
3387         }
3388
3389       /* now propagate the new focus up the widget tree and finally
3390        * set it on the window
3391        */
3392       widget = focus_widget;
3393       while (widget->parent)
3394         {
3395           gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), widget);
3396           widget = widget->parent;
3397         }
3398       if (GTK_IS_WINDOW (widget))
3399         _gtk_window_internal_set_focus (GTK_WINDOW (widget), focus_widget);
3400     }
3401 }
3402
3403 static gboolean
3404 gtk_widget_real_show_help (GtkWidget        *widget,
3405                            GtkWidgetHelpType help_type)
3406 {
3407   if (help_type == GTK_WIDGET_HELP_TOOLTIP)
3408     {
3409       _gtk_tooltips_toggle_keyboard_mode (widget);
3410       return TRUE;
3411     }
3412   else
3413     return FALSE;
3414 }
3415
3416 static gboolean
3417 gtk_widget_real_focus (GtkWidget         *widget,
3418                        GtkDirectionType   direction)
3419 {
3420   if (!GTK_WIDGET_CAN_FOCUS (widget))
3421     return FALSE;
3422   
3423   if (!gtk_widget_is_focus (widget))
3424     {
3425       gtk_widget_grab_focus (widget);
3426       return TRUE;
3427     }
3428   else
3429     return FALSE;
3430 }
3431
3432 /**
3433  * gtk_widget_is_focus:
3434  * @widget: a #GtkWidget
3435  * 
3436  * Determines if the widget is the focus widget within its
3437  * toplevel. (This does not mean that the %HAS_FOCUS flag is
3438  * necessarily set; %HAS_FOCUS will only be set if the
3439  * toplevel widget additionally has the global input focus.)
3440  * 
3441  * Return value: %TRUE if the widget is the focus widget.
3442  **/
3443 gboolean
3444 gtk_widget_is_focus (GtkWidget *widget)
3445 {
3446   GtkWidget *toplevel;
3447
3448   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3449
3450   toplevel = gtk_widget_get_toplevel (widget);
3451   
3452   if (GTK_IS_WINDOW (toplevel))
3453     return widget == GTK_WINDOW (toplevel)->focus_widget;
3454   else
3455     return FALSE;
3456 }
3457
3458 /**
3459  * gtk_widget_grab_default:
3460  * @widget: a #GtkWidget
3461  *
3462  * Causes @widget to become the default widget. @widget must have the
3463  * %GTK_CAN_DEFAULT flag set; typically you have to set this flag
3464  * yourself by calling <literal>GTK_WIDGET_SET_FLAGS (@widget,
3465  * GTK_CAN_DEFAULT)</literal>.  The default widget is activated when the user
3466  * presses Enter in a window.  Default widgets must be activatable,
3467  * that is, gtk_widget_activate() should affect them.
3468  * 
3469  **/
3470 void
3471 gtk_widget_grab_default (GtkWidget *widget)
3472 {
3473   GtkWidget *window;
3474   
3475   g_return_if_fail (GTK_IS_WIDGET (widget));
3476   g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
3477   
3478   window = gtk_widget_get_toplevel (widget);
3479   
3480   if (window && GTK_WIDGET_TOPLEVEL (window))
3481     {
3482        gtk_window_set_default (GTK_WINDOW (window), widget);
3483        g_object_notify (G_OBJECT (widget), "has_default");
3484     }
3485   else
3486     g_warning (G_STRLOC ": widget not within a GtkWindow");
3487 }
3488
3489 /**
3490  * gtk_widget_set_name:
3491  * @widget: a #GtkWidget
3492  * @name: name for the widget
3493  *
3494  * Widgets can be named, which allows you to refer to them from a
3495  * gtkrc file. You can apply a style to widgets with a particular name
3496  * in the gtkrc file. See the documentation for gtkrc files (on the
3497  * same page as the docs for #GtkRcStyle).
3498  * 
3499  **/
3500 void
3501 gtk_widget_set_name (GtkWidget   *widget,
3502                      const gchar *name)
3503 {
3504   g_return_if_fail (GTK_IS_WIDGET (widget));
3505   
3506   if (widget->name)
3507     g_free (widget->name);
3508   widget->name = g_strdup (name);
3509
3510   if (GTK_WIDGET_RC_STYLE (widget))
3511     gtk_widget_reset_rc_style (widget);
3512
3513   g_object_notify (G_OBJECT (widget), "name");
3514 }
3515
3516 /**
3517  * gtk_widget_get_name:
3518  * @widget: a #GtkWidget
3519  * 
3520  * Retrieves the name of a widget. The return value should not be
3521  * freed. See gtk_widget_set_name() for the significance of widget
3522  * names.
3523  * 
3524  * Return value: name of the widget
3525  **/
3526 G_CONST_RETURN gchar*
3527 gtk_widget_get_name (GtkWidget *widget)
3528 {
3529   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3530   
3531   if (widget->name)
3532     return widget->name;
3533   return gtk_type_name (GTK_WIDGET_TYPE (widget));
3534 }
3535
3536 /**
3537  * gtk_widget_set_state:
3538  * @widget: a #GtkWidget
3539  * @state: new state for @widget
3540  *
3541  * This function is for use in widget implementations. Sets the state
3542  * of a widget (insensitive, prelighted, etc.) Usually you should set
3543  * the state using wrapper functions such as gtk_widget_set_sensitive().
3544  * 
3545  **/
3546 void
3547 gtk_widget_set_state (GtkWidget           *widget,
3548                       GtkStateType         state)
3549 {
3550   g_return_if_fail (GTK_IS_WIDGET (widget));
3551
3552   if (state == GTK_WIDGET_STATE (widget))
3553     return;
3554
3555   if (state == GTK_STATE_INSENSITIVE)
3556     gtk_widget_set_sensitive (widget, FALSE);
3557   else
3558     {
3559       GtkStateData data;
3560
3561       data.state = state;
3562       data.state_restoration = FALSE;
3563       data.use_forall = FALSE;
3564       if (widget->parent)
3565         data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
3566       else
3567         data.parent_sensitive = TRUE;
3568
3569       gtk_widget_propagate_state (widget, &data);
3570   
3571       if (GTK_WIDGET_DRAWABLE (widget))
3572         gtk_widget_queue_clear (widget);
3573     }
3574 }
3575
3576 void
3577 gtk_widget_set_app_paintable (GtkWidget *widget,
3578                               gboolean   app_paintable)
3579 {
3580   g_return_if_fail (GTK_IS_WIDGET (widget));
3581
3582   app_paintable = (app_paintable != FALSE);
3583
3584   if (GTK_WIDGET_APP_PAINTABLE (widget) != app_paintable)
3585     {
3586       if (app_paintable)
3587         GTK_WIDGET_SET_FLAGS (widget, GTK_APP_PAINTABLE);
3588       else
3589         GTK_WIDGET_UNSET_FLAGS (widget, GTK_APP_PAINTABLE);
3590
3591       if (GTK_WIDGET_DRAWABLE (widget))
3592         gtk_widget_queue_clear (widget);
3593
3594       g_object_notify (G_OBJECT (widget), "app_paintable");
3595     }
3596 }
3597
3598 /**
3599  * gtk_widget_set_double_buffered:
3600  * @widget: a #GtkWidget
3601  * @double_buffered: %TRUE to double-buffer a widget
3602  *
3603  * Widgets are double buffered by default; you can use this function
3604  * to turn off the buffering. "Double buffered" simply means that
3605  * gdk_window_begin_paint_region() and gdk_window_end_paint() are called
3606  * automatically around expose events sent to the
3607  * widget. gdk_window_begin_paint() diverts all drawing to a widget's
3608  * window to an offscreen buffer, and gdk_window_end_paint() draws the
3609  * buffer to the screen. The result is that users see the window
3610  * update in one smooth step, and don't see individual graphics
3611  * primitives being rendered.
3612  *
3613  * In very simple terms, double buffered widgets don't flicker,
3614  * so you would only use this function to turn off double buffering
3615  * if you had special needs and really knew what you were doing.
3616  * 
3617  **/
3618 void
3619 gtk_widget_set_double_buffered (GtkWidget *widget,
3620                                 gboolean   double_buffered)
3621 {
3622   g_return_if_fail (GTK_IS_WIDGET (widget));
3623
3624   if (double_buffered)
3625     GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
3626   else
3627     GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
3628 }
3629
3630 /**
3631  * gtk_widget_set_redraw_on_allocate:
3632  * @widget: a #GtkWidget
3633  * @redraw_on_allocate: if %TRUE, the entire widget will be redrawn
3634  *   when it is allocated to a new size. Otherwise, only the
3635  *   new portion of the widget will be redrawn.
3636  *
3637  * Sets whether a when a widgets size allocation changes, the entire
3638  * widget is queued for drawing. By default, this setting is %TRUE and
3639  * the entire widget is redrawn on every size change. If your widget
3640  * leaves the upper left are unchanged when made bigger, turning this
3641  * setting on will improve performance.
3642
3643  * Note that for %NO_WINDOW widgets setting this flag to %FALSE turns
3644  * off all allocation on resizing: the widget will not even redraw if
3645  * its position changes; this is to allow containers that don't draw
3646  * anything to avoid excess invalidations. If you set this flag on a
3647  * %NO_WINDOW widget that <emphasis>does</emphasis> draw on @widget->window, 
3648  * you are responsible for invalidating both the old and new allocation 
3649  * of the widget when the widget is moved and responsible for invalidating
3650  * regions newly when the widget increases size.
3651  **/
3652 void
3653 gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
3654                                    gboolean   redraw_on_allocate)
3655 {
3656   g_return_if_fail (GTK_IS_WIDGET (widget));
3657
3658   if (redraw_on_allocate)
3659     GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
3660   else
3661     GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
3662 }
3663
3664 /**
3665  * gtk_widget_set_sensitive:
3666  * @widget: a #GtkWidget
3667  * @sensitive: %TRUE to make the widget sensitive
3668  *
3669  * Sets the sensitivity of a widget. A widget is sensitive if the user
3670  * can interact with it. Insensitive widgets are "grayed out" and the
3671  * user can't interact with them. Insensitive widgets are known as
3672  * "inactive", "disabled", or "ghosted" in some other toolkits.
3673  * 
3674  **/
3675 void
3676 gtk_widget_set_sensitive (GtkWidget *widget,
3677                           gboolean   sensitive)
3678 {
3679   GtkStateData data;
3680
3681   g_return_if_fail (GTK_IS_WIDGET (widget));
3682
3683   sensitive = (sensitive != FALSE);
3684
3685   if (sensitive == (GTK_WIDGET_SENSITIVE (widget) != FALSE))
3686     return;
3687
3688   if (sensitive)
3689     {
3690       GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
3691       data.state = GTK_WIDGET_SAVED_STATE (widget);
3692     }
3693   else
3694     {
3695       GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
3696       data.state = GTK_WIDGET_STATE (widget);
3697     }
3698   data.state_restoration = TRUE;
3699   data.use_forall = TRUE;
3700
3701   if (widget->parent)
3702     data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
3703   else
3704     data.parent_sensitive = TRUE;
3705
3706   gtk_widget_propagate_state (widget, &data);
3707   if (GTK_WIDGET_DRAWABLE (widget))
3708     gtk_widget_queue_clear (widget);
3709
3710   g_object_notify (G_OBJECT (widget), "sensitive");
3711 }
3712
3713 /**
3714  * gtk_widget_set_parent:
3715  * @widget: a #GtkWidget
3716  * @parent: parent container
3717  *
3718  * This function is useful only when implementing subclasses of #GtkContainer.
3719  * Sets the container as the parent of @widget, and takes care of
3720  * some details such as updating the state and style of the child
3721  * to reflect its new location. The opposite function is
3722  * gtk_widget_unparent().
3723  * 
3724  **/
3725 void
3726 gtk_widget_set_parent (GtkWidget *widget,
3727                        GtkWidget *parent)
3728 {
3729   GtkStateData data;
3730   
3731   g_return_if_fail (GTK_IS_WIDGET (widget));
3732   g_return_if_fail (widget->parent == NULL);
3733   g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
3734   g_return_if_fail (GTK_IS_WIDGET (parent));
3735   g_return_if_fail (widget != parent);
3736
3737   /* keep this function in sync with gtk_menu_attach_to_widget()
3738    */
3739
3740   gtk_widget_ref (widget);
3741   gtk_object_sink (GTK_OBJECT (widget));
3742   widget->parent = parent;
3743
3744   if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL)
3745     data.state = GTK_WIDGET_STATE (parent);
3746   else
3747     data.state = GTK_WIDGET_STATE (widget);
3748   data.state_restoration = FALSE;
3749   data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (parent) != FALSE);
3750   data.use_forall = GTK_WIDGET_IS_SENSITIVE (parent) != GTK_WIDGET_IS_SENSITIVE (widget);
3751
3752   gtk_widget_propagate_state (widget, &data);
3753   
3754   gtk_widget_reset_rc_styles (widget);
3755
3756   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], NULL);
3757   if (GTK_WIDGET_ANCHORED (widget->parent))
3758     _gtk_widget_propagate_hierarchy_changed (widget, NULL);
3759   g_object_notify (G_OBJECT (widget), "parent");
3760
3761   /* Enforce realized/mapped invariants
3762    */
3763   if (GTK_WIDGET_REALIZED (widget->parent))
3764     gtk_widget_realize (widget);
3765
3766   if (GTK_WIDGET_VISIBLE (widget->parent) &&
3767       GTK_WIDGET_VISIBLE (widget))
3768     {
3769       if (GTK_WIDGET_CHILD_VISIBLE (widget) &&
3770           GTK_WIDGET_MAPPED (widget->parent))
3771         gtk_widget_map (widget);
3772
3773       gtk_widget_queue_resize (widget);
3774     }
3775 }
3776
3777 /**
3778  * gtk_widget_get_parent:
3779  * @widget: a #GtkWidget
3780  *
3781  * Returns the parent container of @widget.
3782  *
3783  * Return value: the parent container of @widget, or %NULL
3784  **/
3785 GtkWidget *
3786 gtk_widget_get_parent (GtkWidget *widget)
3787 {
3788   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3789
3790   return widget->parent;
3791 }
3792
3793 /*****************************************
3794  * Widget styles
3795  * see docs/styles.txt
3796  *****************************************/
3797
3798 /**
3799  * gtk_widget_set_style:
3800  * @widget: a #GtkWidget
3801  * @style: a #GtkStyle, or %NULL to remove the effect of a previous
3802  *         gtk_widget_set_style() and go back to the default style
3803  *
3804  * Sets the #GtkStyle for a widget (@widget->style). You probably don't
3805  * want to use this function; it interacts badly with themes, because
3806  * themes work by replacing the #GtkStyle. Instead, use
3807  * gtk_widget_modify_style().
3808  * 
3809  **/
3810 void
3811 gtk_widget_set_style (GtkWidget *widget,
3812                       GtkStyle  *style)
3813 {
3814   g_return_if_fail (GTK_IS_WIDGET (widget));
3815
3816   if (style)
3817     {
3818       gboolean initial_emission;
3819
3820       initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3821       
3822       GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
3823       GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
3824       
3825       gtk_widget_set_style_internal (widget, style, initial_emission);
3826     }
3827   else
3828     {
3829       if (GTK_WIDGET_USER_STYLE (widget))
3830         gtk_widget_reset_rc_style (widget);
3831     }
3832 }
3833
3834 /**
3835  * gtk_widget_ensure_style:
3836  * @widget: a #GtkWidget
3837  *
3838  * Ensures that @widget has a style (@widget->style). Not a very useful
3839  * function; most of the time, if you want the style, the widget is
3840  * realized, and realized widgets are guaranteed to have a style
3841  * already.
3842  * 
3843  **/
3844 void
3845 gtk_widget_ensure_style (GtkWidget *widget)
3846 {
3847   g_return_if_fail (GTK_IS_WIDGET (widget));
3848
3849   if (!GTK_WIDGET_USER_STYLE (widget) &&
3850       !GTK_WIDGET_RC_STYLE (widget))
3851     gtk_widget_reset_rc_style (widget);
3852 }
3853
3854 /* Look up the RC style for this widget, unsetting any user style that
3855  * may be in effect currently
3856  **/
3857 static void
3858 gtk_widget_reset_rc_style (GtkWidget *widget)
3859 {
3860   GtkStyle *new_style;
3861   gboolean initial_emission;
3862   
3863   g_return_if_fail (GTK_IS_WIDGET (widget));
3864
3865   initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3866
3867   GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3868   GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
3869
3870   new_style = gtk_rc_get_style (widget);
3871   if (!new_style)
3872     new_style = gtk_widget_get_default_style ();
3873
3874   if (initial_emission || new_style != widget->style)
3875     gtk_widget_set_style_internal (widget, new_style, initial_emission);
3876 }
3877
3878 /**
3879  * gtk_widget_get_style:
3880  * @widget: a #GtkWidget
3881  * 
3882  * Simply an accessor function that returns @widget->style.
3883  * 
3884  * Return value: the widget's #GtkStyle
3885  **/
3886 GtkStyle*
3887 gtk_widget_get_style (GtkWidget *widget)
3888 {
3889   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3890   
3891   return widget->style;
3892 }
3893
3894 /**
3895  * gtk_widget_modify_style:
3896  * @widget: a #GtkWidget
3897  * @style: the #GtkRcStyle holding the style modifications
3898  * 
3899  * Modifies style values on the widget. Modifications made using this
3900  * technique take precedence over style values set via an RC file,
3901  * however, they will be overriden if a style is explicitely set on
3902  * the widget using gtk_widget_set_style(). The #GtkRcStyle structure
3903  * is designed so each field can either be set or unset, so it is
3904  * possible, using this function, to modify some style values and
3905  * leave the others unchanged.
3906  *
3907  * Note that modifications made with this function are not cumulative
3908  * with previous calls to gtk_widget_modify_style() or with such
3909  * functions as gtk_widget_modify_fg(). If you wish to retain
3910  * previous values, you must first call gtk_widget_get_modifier_style(),
3911  * make your modifications to the returned style, then call
3912  * gtk_widget_modify_style() with that style. On the other hand,
3913  * if you first call gtk_widget_modify_style(), subsequent calls
3914  * to such functions gtk_widget_modify_fg() will have a cumulative
3915  * effect with the initial modifications.
3916  **/
3917 void       
3918 gtk_widget_modify_style (GtkWidget      *widget,
3919                          GtkRcStyle     *style)
3920 {
3921   GtkRcStyle *old_style;
3922
3923   g_return_if_fail (GTK_IS_WIDGET (widget));
3924   g_return_if_fail (GTK_IS_RC_STYLE (style));
3925   
3926   old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3927                                          quark_rc_style);
3928
3929   gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3930                                   quark_rc_style,
3931                                   gtk_rc_style_copy (style),
3932                                   (GtkDestroyNotify)gtk_rc_style_unref);
3933
3934   /* note that "style" may be invalid here if it was the old
3935    * modifier style and the only reference was our own.
3936    */
3937   
3938   if (GTK_WIDGET_RC_STYLE (widget))
3939     gtk_widget_reset_rc_style (widget);
3940 }
3941
3942 /**
3943  * gtk_widget_get_modifier_style:
3944  * @widget: a #GtkWidget
3945  * 
3946  * Returns the current modifier style for the widget. (As set by
3947  * gtk_widget_modify_style().) If no style has previously set, a new
3948  * #GtkRcStyle will be created with all values unset, and set as the
3949  * modifier style for the widget. If you make changes to this rc
3950  * style, you must call gtk_widget_modify_style(), passing in the
3951  * returned rc style, to make sure that your changes take effect.
3952  *
3953  * Caution: passing the style back to gtk_widget_modify_style() will
3954  * normally end up destroying it, because gtk_widget_modify_style() copies
3955  * the passed-in style and sets the copy as the new modifier style,
3956  * thus dropping any reference to the old modifier style. Add a reference
3957  * to the modifier style if you want to keep it alive.
3958  * 
3959  * Return value: the modifier style for the widget. This rc style is
3960  *   owned by the widget. If you want to keep a pointer to value this
3961  *   around, you must add a refcount using gtk_rc_style_ref().
3962  **/
3963 GtkRcStyle *
3964 gtk_widget_get_modifier_style (GtkWidget      *widget)
3965 {
3966   GtkRcStyle *rc_style;
3967   
3968   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3969
3970   rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3971                                         quark_rc_style);
3972
3973   if (!rc_style)
3974     {
3975       rc_style = gtk_rc_style_new ();
3976       gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3977                                       quark_rc_style,
3978                                       rc_style,
3979                                       (GtkDestroyNotify)gtk_rc_style_unref);
3980     }
3981
3982   return rc_style;
3983 }
3984
3985 static void
3986 gtk_widget_modify_color_component (GtkWidget     *widget,
3987                                    GtkRcFlags     component,
3988                                    GtkStateType   state,
3989                                    GdkColor      *color)
3990 {
3991   GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);  
3992
3993   switch (component)
3994     {
3995     case GTK_RC_FG:
3996       rc_style->fg[state] = *color;
3997       break;
3998     case GTK_RC_BG:
3999       rc_style->bg[state] = *color;
4000       break;
4001     case GTK_RC_TEXT:
4002       rc_style->text[state] = *color;
4003        break;
4004     case GTK_RC_BASE:
4005       rc_style->base[state] = *color;
4006       break;
4007     default:
4008       g_assert_not_reached();
4009     }
4010
4011   rc_style->color_flags[state] |= component;
4012
4013   gtk_widget_modify_style (widget, rc_style);
4014 }
4015
4016 /**
4017  * gtk_widget_modify_fg:
4018  * @widget: a #GtkWidget.
4019  * @state: the state for which to set the foreground color.
4020  * @color: the color to assign (does not need to be allocated).
4021  * 
4022  * Sets the foreground color for a widget in a particular state.  All
4023  * other style values are left untouched. See also
4024  * gtk_widget_modify_style().
4025  **/
4026 void
4027 gtk_widget_modify_fg (GtkWidget   *widget,
4028                       GtkStateType state,
4029                       GdkColor    *color)
4030 {
4031   g_return_if_fail (GTK_IS_WIDGET (widget));
4032   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4033   g_return_if_fail (color != NULL);
4034
4035   gtk_widget_modify_color_component (widget, GTK_RC_FG, state, color);
4036 }
4037
4038 /**
4039  * gtk_widget_modify_bg:
4040  * @widget: a #GtkWidget.
4041  * @state: the state for which to set the background color.
4042  * @color: the color to assign (does not need to be allocated).
4043  * 
4044  * Sets the background color for a widget in a particular state.  All
4045  * other style values are left untouched. See also
4046  * gtk_widget_modify_style().
4047  **/
4048 void
4049 gtk_widget_modify_bg (GtkWidget   *widget,
4050                       GtkStateType state,
4051                       GdkColor    *color)
4052 {
4053   g_return_if_fail (GTK_IS_WIDGET (widget));
4054   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4055   g_return_if_fail (color != NULL);
4056
4057   gtk_widget_modify_color_component (widget, GTK_RC_BG, state, color);
4058 }
4059
4060 /**
4061  * gtk_widget_modify_text:
4062  * @widget: a #GtkWidget.
4063  * @state: the state for which to set the text color.
4064  * @color: the color to assign (does not need to be allocated).
4065  * 
4066  * Sets the text color for a widget in a particular state.  All other
4067  * style values are left untouched. The text color is the foreground
4068  * color used along with the base color (see gtk_widget_modify_base())
4069  * for widgets such as #GtkEntry and #GtkTextView. See also
4070  * gtk_widget_modify_style().
4071  **/
4072 void
4073 gtk_widget_modify_text (GtkWidget   *widget,
4074                         GtkStateType state,
4075                         GdkColor    *color)
4076 {
4077   g_return_if_fail (GTK_IS_WIDGET (widget));
4078   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4079   g_return_if_fail (color != NULL);
4080
4081   gtk_widget_modify_color_component (widget, GTK_RC_TEXT, state, color);
4082 }
4083
4084 /**
4085  * gtk_widget_modify_base:
4086  * @widget: a #GtkWidget.
4087  * @state: the state for which to set the base color.
4088  * @color: the color to assign (does not need to be allocated).
4089  * 
4090  * Sets the base color for a widget in a particular state.
4091  * All other style values are left untouched. The base color
4092  * is the background color used along with the text color
4093  * (see gtk_widget_modify_text()) for widgets such as #GtkEntry
4094  * and #GtkTextView. See also gtk_widget_modify_style().
4095  **/
4096 void
4097 gtk_widget_modify_base (GtkWidget  *widget,
4098                         GtkStateType state,
4099                         GdkColor    *color)
4100 {
4101   g_return_if_fail (GTK_IS_WIDGET (widget));
4102   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
4103   g_return_if_fail (color != NULL);
4104
4105   gtk_widget_modify_color_component (widget, GTK_RC_BASE, state, color);
4106 }
4107
4108 /**
4109  * gtk_widget_modify_font:
4110  * @widget: a #GtkWidget
4111  * @font_desc: the font description to use
4112  * 
4113  * Sets the font to use for a widget.  All other style values are left
4114  * untouched. See also gtk_widget_modify_style().
4115  **/
4116 void
4117 gtk_widget_modify_font (GtkWidget            *widget,
4118                         PangoFontDescription *font_desc)
4119 {
4120   GtkRcStyle *rc_style;
4121
4122   g_return_if_fail (GTK_IS_WIDGET (widget));
4123   g_return_if_fail (font_desc != NULL);
4124
4125   rc_style = gtk_widget_get_modifier_style (widget);  
4126
4127   if (rc_style->font_desc)
4128     pango_font_description_free (rc_style->font_desc);
4129   
4130   rc_style->font_desc = pango_font_description_copy (font_desc);
4131
4132   gtk_widget_modify_style (widget, rc_style);
4133 }
4134
4135 static void
4136 gtk_widget_direction_changed (GtkWidget        *widget,
4137                               GtkTextDirection  previous_direction)
4138 {
4139   gtk_widget_queue_resize (widget);
4140 }
4141
4142 static void
4143 gtk_widget_style_set (GtkWidget *widget,
4144                       GtkStyle  *previous_style)
4145 {
4146   if (GTK_WIDGET_REALIZED (widget) &&
4147       !GTK_WIDGET_NO_WINDOW (widget))
4148     gtk_style_set_background (widget->style, widget->window, widget->state);
4149 }
4150
4151 static void
4152 gtk_widget_set_style_internal (GtkWidget *widget,
4153                                GtkStyle  *style,
4154                                gboolean   initial_emission)
4155 {
4156   g_object_ref (G_OBJECT (widget));
4157   g_object_freeze_notify (G_OBJECT (widget));
4158
4159   if (widget->style != style || initial_emission)
4160     {
4161       PangoContext *context = gtk_widget_peek_pango_context (widget);
4162       if (context)
4163         pango_context_set_font_description (context, style->font_desc);
4164     }
4165   
4166   if (widget->style != style)
4167     {
4168       GtkStyle *previous_style;
4169
4170       if (GTK_WIDGET_REALIZED (widget))
4171         {
4172           gtk_widget_reset_shapes (widget);
4173           gtk_style_detach (widget->style);
4174         }
4175       
4176       previous_style = widget->style;
4177       widget->style = style;
4178       g_object_ref (widget->style);
4179       
4180       if (GTK_WIDGET_REALIZED (widget))
4181         widget->style = gtk_style_attach (widget->style, widget->window);
4182
4183       gtk_signal_emit (GTK_OBJECT (widget),
4184                        widget_signals[STYLE_SET],
4185                        initial_emission ? NULL : previous_style);
4186       g_object_unref (previous_style);
4187
4188       if (widget->parent && !initial_emission)
4189         gtk_widget_queue_resize (widget);
4190     }
4191   else if (initial_emission)
4192     gtk_signal_emit (GTK_OBJECT (widget),
4193                      widget_signals[STYLE_SET],
4194                      NULL);
4195   g_object_notify (G_OBJECT (widget), "style");
4196   g_object_thaw_notify (G_OBJECT (widget));
4197   g_object_unref (G_OBJECT (widget));
4198 }
4199
4200 static void
4201 gtk_widget_propagate_hierarchy_changed_recurse (GtkWidget *widget,
4202                                                 gpointer   client_data)
4203 {
4204   gboolean new_anchored;
4205
4206   new_anchored = GTK_WIDGET_TOPLEVEL (widget) ||
4207                  (widget->parent && GTK_WIDGET_ANCHORED (widget->parent));
4208
4209   if (GTK_WIDGET_ANCHORED (widget) != new_anchored)
4210     {
4211       gtk_widget_ref (widget);
4212       
4213       if (new_anchored)
4214         GTK_PRIVATE_SET_FLAG (widget, GTK_ANCHORED);
4215       else
4216         GTK_PRIVATE_UNSET_FLAG (widget, GTK_ANCHORED);
4217       
4218       g_signal_emit (GTK_OBJECT (widget), widget_signals[HIERARCHY_CHANGED],
4219                      0, client_data);
4220   
4221       if (GTK_IS_CONTAINER (widget))
4222         gtk_container_forall (GTK_CONTAINER (widget),
4223                               gtk_widget_propagate_hierarchy_changed_recurse,
4224                               client_data);
4225       
4226       gtk_widget_unref (widget);
4227     }
4228 }
4229
4230 /**
4231  * _gtk_widget_propagate_hierarchy_changed:
4232  * @widget: a #GtkWidget
4233  * @previous_toplevel: Previous toplevel
4234  * 
4235  * Propagates changes in the anchored state to a widget and all
4236  * children, unsetting or setting the %ANCHORED flag, and
4237  * emitting ::hierarchy_changed.
4238  **/
4239 void
4240 _gtk_widget_propagate_hierarchy_changed (GtkWidget    *widget,
4241                                          GtkWidget    *previous_toplevel)
4242 {
4243   if (previous_toplevel)
4244     g_object_ref (previous_toplevel);
4245
4246   gtk_widget_propagate_hierarchy_changed_recurse (widget, previous_toplevel);
4247   
4248   if (previous_toplevel)
4249     g_object_unref (previous_toplevel);
4250 }
4251
4252 static void
4253 reset_rc_styles_recurse (GtkWidget *widget, gpointer data)
4254 {
4255   if (GTK_WIDGET_RC_STYLE (widget))
4256     gtk_widget_reset_rc_style (widget);
4257   
4258   if (GTK_IS_CONTAINER (widget))
4259     gtk_container_forall (GTK_CONTAINER (widget),
4260                           reset_rc_styles_recurse,
4261                           NULL);
4262 }
4263
4264 void
4265 gtk_widget_reset_rc_styles (GtkWidget *widget)
4266 {
4267   g_return_if_fail (GTK_IS_WIDGET (widget));
4268
4269   reset_rc_styles_recurse (widget, NULL);
4270 }
4271
4272 /**
4273  * gtk_widget_get_default_style:
4274  * 
4275  * Returns the default style used by all widgets initially.
4276  * 
4277  * Returns: the default style. This #GtkStyle object is owned by GTK+ and
4278  * should not be modified or freed.
4279  */ 
4280 GtkStyle*
4281 gtk_widget_get_default_style (void)
4282 {
4283   if (!gtk_default_style)
4284     {
4285       gtk_default_style = gtk_style_new ();
4286       g_object_ref (gtk_default_style);
4287     }
4288   
4289   return gtk_default_style;
4290 }
4291
4292 static PangoContext *
4293 gtk_widget_peek_pango_context (GtkWidget *widget)
4294 {
4295   return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
4296 }
4297
4298 /**
4299  * gtk_widget_get_pango_context:
4300  * @widget: a #GtkWidget
4301  * 
4302  * Gets a #PangoContext with the appropriate colormap, font description
4303  * and base direction for this widget. Unlike the context returned
4304  * by gtk_widget_create_pango_context(), this context is owned by
4305  * the widget (it can be used as long as widget exists), and will
4306  * be updated to match any changes to the widget's attributes.
4307  *
4308  * If you create and keep a #PangoLayout using this context, you must
4309  * deal with changes to the context by calling pango_layout_context_changed()
4310  * on the layout in response to the ::style_set and ::direction_set signals
4311  * for the widget.
4312  *
4313  * Return value: the #PangoContext for the widget.
4314  **/
4315 PangoContext *
4316 gtk_widget_get_pango_context (GtkWidget *widget)
4317 {
4318   PangoContext *context;
4319
4320   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4321   
4322   context = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
4323   if (!context)
4324     {
4325       context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
4326       gtk_object_set_data_by_id_full (GTK_OBJECT (widget), quark_pango_context, context,
4327                                       (GDestroyNotify) g_object_unref);
4328     }
4329
4330   return context;
4331 }
4332
4333 /**
4334  * gtk_widget_create_pango_context:
4335  * @widget: a #GtkWidget
4336  * 
4337  * Creates a new #PangoContext with the appropriate colormap,
4338  * font description, and base direction for drawing text for
4339  * this widget. See also gtk_widget_get_pango_context().
4340  * 
4341  * Return value: the new #PangoContext
4342  **/
4343 PangoContext *
4344 gtk_widget_create_pango_context (GtkWidget *widget)
4345 {
4346   PangoContext *context;
4347
4348   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4349
4350   context = gdk_pango_context_get ();
4351
4352   gdk_pango_context_set_colormap (context, gtk_widget_get_colormap (widget));
4353   pango_context_set_base_dir (context,
4354                               gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
4355                                 PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
4356   pango_context_set_font_description (context, widget->style->font_desc);
4357   pango_context_set_language (context, gtk_get_default_language ());
4358
4359   return context;
4360 }
4361
4362 /**
4363  * gtk_widget_create_pango_layout:
4364  * @widget: a #GtkWidget
4365  * @text:   text to set on the layout (can be %NULL)
4366  * 
4367  * Creates a new #PangoLayout with the appropriate colormap,
4368  * font description, and base direction for drawing text for
4369  * this widget.
4370  *
4371  * If you keep a #PangoLayout created in this way around, in order
4372  * notify the layout of changes to the base direction or font of this
4373  * widget, you must call pango_layout_context_changed() in response to
4374  * the ::style_set and ::direction_set signals for the widget.
4375  * 
4376  * Return value: the new #PangoLayout
4377  **/
4378 PangoLayout *
4379 gtk_widget_create_pango_layout (GtkWidget   *widget,
4380                                 const gchar *text)
4381 {
4382   PangoLayout *layout;
4383   PangoContext *context;
4384
4385   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4386
4387   context = gtk_widget_get_pango_context (widget);
4388   layout = pango_layout_new (context);
4389
4390   if (text)
4391     pango_layout_set_text (layout, text, -1);
4392
4393   return layout;
4394 }
4395
4396 /**
4397  * gtk_widget_render_icon:
4398  * @widget: a #GtkWidget
4399  * @stock_id: a stock ID
4400  * @size: a stock size
4401  * @detail: render detail to pass to theme engine
4402  * 
4403  * A convenience function that uses the theme engine and RC file
4404  * settings for @widget to look up @stock_id and render it to
4405  * a pixbuf. @stock_id should be a stock icon ID such as
4406  * #GTK_STOCK_OPEN or #GTK_STOCK_OK. @size should be a size
4407  * such as #GTK_ICON_SIZE_MENU. @detail should be a string that
4408  * identifies the widget or code doing the rendering, so that
4409  * theme engines can special-case rendering for that widget or code.
4410  * 
4411  * Return value: a new pixbuf, or %NULL if the stock ID wasn't known
4412  **/
4413 GdkPixbuf*
4414 gtk_widget_render_icon (GtkWidget      *widget,
4415                         const gchar    *stock_id,
4416                         GtkIconSize     size,
4417                         const gchar    *detail)
4418 {
4419   GtkIconSet *icon_set;
4420   GdkPixbuf *retval;
4421   
4422   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4423   g_return_val_if_fail (stock_id != NULL, NULL);
4424   g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID, NULL);
4425   
4426   gtk_widget_ensure_style (widget);
4427   
4428   icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
4429
4430   if (icon_set == NULL)
4431     return NULL;
4432
4433   retval = gtk_icon_set_render_icon (icon_set,
4434                                      widget->style,
4435                                      gtk_widget_get_direction (widget),
4436                                      GTK_WIDGET_STATE (widget),
4437                                      size,
4438                                      widget,
4439                                      detail);
4440
4441   return retval;
4442 }
4443
4444 /**
4445  * gtk_widget_set_parent_window:
4446  * @widget: a #GtkWidget.
4447  * @parent_window: the new parent window.
4448  *  
4449  * Sets a non default parent window for @widget.
4450  **/
4451 void
4452 gtk_widget_set_parent_window   (GtkWidget           *widget,
4453                                 GdkWindow           *parent_window)
4454 {
4455   GdkWindow *old_parent_window;
4456
4457   g_return_if_fail (GTK_IS_WIDGET (widget));
4458   
4459   old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
4460                                                  quark_parent_window);
4461
4462   if (parent_window != old_parent_window)
4463     {
4464       gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_parent_window, 
4465                                  parent_window);
4466       if (old_parent_window)
4467         gdk_window_unref (old_parent_window);
4468       if (parent_window)
4469         gdk_window_ref (parent_window);
4470     }
4471 }
4472
4473
4474 /**
4475  * gtk_widget_set_child_visible:
4476  * @widget: a #GtkWidget
4477  * @is_visible: if %TRUE, @widget should be mapped along with its parent.
4478  *
4479  * Sets whether @widget should be mapped along with its when its parent
4480  * is mapped and @widget has been shown with gtk_widget_show(). 
4481  *
4482  * The child visibility can be set for widget before it is added to
4483  * a container with gtk_widget_set_parent(), to avoid mapping
4484  * children unnecessary before immediately unmapping them. However
4485  * it will be reset to its default state of %TRUE when the widget
4486  * is removed from a container.
4487  * 
4488  * Note that changing the child visibility of a widget does not
4489  * queue a resize on the widget. Most of the time, the size of
4490  * a widget is computed from all visible children, whether or
4491  * not they are mapped. If this is not the case, the container
4492  * can queue a resize itself.
4493  *
4494  * This function is only useful for container implementations and
4495  * never should be called by an application.
4496  **/
4497 void
4498 gtk_widget_set_child_visible (GtkWidget *widget,
4499                               gboolean   is_visible)
4500 {
4501   g_return_if_fail (GTK_IS_WIDGET (widget));
4502   g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
4503
4504   if (is_visible)
4505     GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
4506   else
4507     GTK_PRIVATE_UNSET_FLAG (widget, GTK_CHILD_VISIBLE);
4508   if (GTK_WIDGET_REALIZED (widget->parent))
4509     {
4510       if (GTK_WIDGET_MAPPED (widget->parent) &&
4511           GTK_WIDGET_CHILD_VISIBLE (widget) &&
4512           GTK_WIDGET_VISIBLE (widget))
4513         gtk_widget_map (widget);
4514       else
4515         gtk_widget_unmap (widget);
4516     }
4517 }
4518
4519 /**
4520  * gtk_widget_get_child_visible:
4521  * @widget: a #GtkWidget
4522  * 
4523  * Gets the value set with gtk_widget_set_child_visible().
4524  * If you feel a need to use this function, your code probably
4525  * needs reorganization. 
4526  *
4527  * This function is only useful for container implementations and
4528  * never should be called by an application.
4529  *
4530  * Return value: %TRUE if the widget is mapped with the parent.
4531  **/
4532 gboolean
4533 gtk_widget_get_child_visible (GtkWidget *widget)
4534 {
4535   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4536   
4537   return GTK_WIDGET_CHILD_VISIBLE (widget);
4538 }
4539
4540 /**
4541  * gtk_widget_get_parent_window:
4542  * @widget: a #GtkWidget.
4543  * @returns: the parent window of @widget.
4544  * 
4545  * Gets @widget's parent window.
4546  **/
4547 GdkWindow *
4548 gtk_widget_get_parent_window   (GtkWidget           *widget)
4549 {
4550   GdkWindow *parent_window;
4551
4552   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4553   g_return_val_if_fail (widget->parent != NULL, NULL);
4554   
4555   parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
4556                                              quark_parent_window);
4557
4558   return (parent_window != NULL) ? parent_window : widget->parent->window;
4559 }
4560
4561 /**
4562  * gtk_widget_child_focus:
4563  * @widget: a #GtkWidget
4564  * @direction: direction of focus movement
4565  *
4566  * This function is used by custom widget implementations; if you're
4567  * writing an app, you'd use gtk_widget_grab_focus() to move the focus
4568  * to a particular widget, and gtk_container_set_focus_chain() to
4569  * change the focus tab order. So you may want to investigate those
4570  * functions instead.
4571  * 
4572  * gtk_widget_child_focus() is called by containers as the user moves
4573  * around the window using keyboard shortcuts. @direction indicates
4574  * what kind of motion is taking place (up, down, left, right, tab
4575  * forward, tab backward).  gtk_widget_child_focus() invokes the
4576  * "focus" signal on #GtkWidget; widgets override the default handler
4577  * for this signal in order to implement appropriate focus behavior.
4578  *
4579  * The "focus" default handler for a widget should return %TRUE if
4580  * moving in @direction left the focus on a focusable location inside
4581  * that widget, and %FALSE if moving in @direction moved the focus
4582  * outside the widget. If returning %TRUE, widgets normally
4583  * call gtk_widget_grab_focus() to place the focus accordingly;
4584  * if returning %FALSE, they don't modify the current focus location.
4585  * 
4586  * This function replaces gtk_container_focus() from GTK+ 1.2.  It was
4587  * necessary to check that the child was visible, sensitive, and
4588  * focusable before calling
4589  * gtk_container_focus(). gtk_widget_child_focus() returns %FALSE if
4590  * the widget is not currently in a focusable state, so there's no
4591  * need for those checks.
4592  * 
4593  * Return value: %TRUE if focus ended up inside @widget
4594  **/
4595 gboolean
4596 gtk_widget_child_focus (GtkWidget       *widget,
4597                         GtkDirectionType direction)
4598 {
4599   gboolean return_val;
4600
4601   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4602
4603   if (!GTK_WIDGET_VISIBLE (widget) ||
4604       !GTK_WIDGET_IS_SENSITIVE (widget))
4605     return FALSE;
4606
4607   /* child widgets must set CAN_FOCUS, containers
4608    * don't have to though.
4609    */
4610   if (!GTK_IS_CONTAINER (widget) &&
4611       !GTK_WIDGET_CAN_FOCUS (widget))
4612     return FALSE;
4613   
4614   gtk_signal_emit (GTK_OBJECT (widget),
4615                    widget_signals[FOCUS],
4616                    direction, &return_val);
4617
4618   return return_val;
4619 }
4620
4621 /**
4622  * gtk_widget_set_uposition:
4623  * @widget: a #GtkWidget
4624  * @x: x position; -1 to unset x; -2 to leave x unchanged
4625  * @y: y position; -1 to unset y; -2 to leave y unchanged
4626  * 
4627  *
4628  * Sets the position of a widget. The funny "u" in the name comes from
4629  * the "user position" hint specified by the X Window System, and
4630  * exists for legacy reasons. This function doesn't work if a widget
4631  * is inside a container; it's only really useful on #GtkWindow.
4632  *
4633  * Don't use this function to center dialogs over the main application
4634  * window; most window managers will do the centering on your behalf
4635  * if you call gtk_window_set_transient_for(), and it's really not
4636  * possible to get the centering to work correctly in all cases from
4637  * application code. But if you insist, use gtk_window_set_position()
4638  * to set #GTK_WIN_POS_CENTER_ON_PARENT, don't do the centering
4639  * manually.
4640  *
4641  * Note that although @x and @y can be individually unset, the position
4642  * is not honoured unless both @x and @y are set.
4643  **/
4644 void
4645 gtk_widget_set_uposition (GtkWidget *widget,
4646                           gint       x,
4647                           gint       y)
4648 {
4649   /* FIXME this function is the only place that aux_info->x and
4650    * aux_info->y are even used I believe, and this function is
4651    * deprecated. Should be cleaned up.
4652    */
4653   
4654   GtkWidgetAuxInfo *aux_info;
4655   
4656   g_return_if_fail (GTK_IS_WIDGET (widget));
4657   
4658   aux_info =_gtk_widget_get_aux_info (widget, TRUE);
4659   
4660   if (x > -2)
4661     {
4662       if (x == -1)
4663         aux_info->x_set = FALSE;
4664       else
4665         {
4666           aux_info->x_set = TRUE;
4667           aux_info->x = x;
4668         }
4669     }
4670
4671   if (y > -2)
4672     {
4673       if (y == -1)
4674         aux_info->y_set = FALSE;
4675       else
4676         {
4677           aux_info->y_set = TRUE;
4678           aux_info->y = y;
4679         }
4680     }
4681
4682   if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
4683     _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
4684   
4685   if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
4686     gtk_widget_size_allocate (widget, &widget->allocation);
4687 }
4688
4689 /**
4690  * gtk_widget_set_usize:
4691  * @widget: a #GtkWidget
4692  * @width: minimum width, or -1 to unset
4693  * @height: minimum height, or -1 to unset
4694  *
4695  * This function is deprecated; use gtk_widget_set_size_request()
4696  * instead.
4697  * 
4698  * Sets the minimum size of a widget; that is, the widget's size
4699  * request will be @width by @height. You can use this function to
4700  * force a widget to be either larger or smaller than it is. The
4701  * strange "usize" name dates from the early days of GTK+, and derives
4702  * from X Window System terminology. In many cases,
4703  * gtk_window_set_default_size() is a better choice for toplevel
4704  * windows than this function; setting the default size will still
4705  * allow users to shrink the window. Setting the usize will force them
4706  * to leave the window at least as large as the usize. When dealing
4707  * with window sizes, gtk_window_set_geometry_hints() can be a useful
4708  * function as well.
4709  * 
4710  * Note the inherent danger of setting any fixed size - themes,
4711  * translations into other languages, different fonts, and user action
4712  * can all change the appropriate size for a given widget. So, it's
4713  * basically impossible to hardcode a size that will always be
4714  * correct.
4715  * 
4716  **/
4717 void
4718 gtk_widget_set_usize (GtkWidget *widget,
4719                       gint       width,
4720                       gint       height)
4721 {
4722   GtkWidgetAuxInfo *aux_info;
4723   
4724   g_return_if_fail (GTK_IS_WIDGET (widget));
4725   
4726   g_object_freeze_notify (G_OBJECT (widget));
4727
4728   aux_info =_gtk_widget_get_aux_info (widget, TRUE);
4729   
4730   if (width > -2)
4731     {
4732       g_object_notify (G_OBJECT (widget), "width_request");
4733       aux_info->width = width;
4734     }
4735   if (height > -2)
4736     {
4737       g_object_notify (G_OBJECT (widget), "height_request");  
4738       aux_info->height = height;
4739     }
4740   
4741   if (GTK_WIDGET_VISIBLE (widget))
4742     gtk_widget_queue_resize (widget);
4743
4744   g_object_thaw_notify (G_OBJECT (widget));
4745 }
4746
4747 /**
4748  * gtk_widget_set_size_request:
4749  * @widget: a #GtkWidget
4750  * @width: width @widget should request, or -1 to unset
4751  * @height: height @widget should request, or -1 to unset
4752  *
4753  * Sets the minimum size of a widget; that is, the widget's size
4754  * request will be @width by @height. You can use this function to
4755  * force a widget to be either larger or smaller than it normally
4756  * would be.
4757  *
4758  * In most cases, gtk_window_set_default_size() is a better choice for
4759  * toplevel windows than this function; setting the default size will
4760  * still allow users to shrink the window. Setting the size request
4761  * will force them to leave the window at least as large as the size
4762  * request. When dealing with window sizes,
4763  * gtk_window_set_geometry_hints() can be a useful function as well.
4764  * 
4765  * Note the inherent danger of setting any fixed size - themes,
4766  * translations into other languages, different fonts, and user action
4767  * can all change the appropriate size for a given widget. So, it's
4768  * basically impossible to hardcode a size that will always be
4769  * correct.
4770  *
4771  * The size request of a widget is the smallest size a widget can
4772  * accept while still functioning well and drawing itself correctly.
4773  * However in some strange cases a widget may be allocated less than
4774  * its requested size, and in many cases a widget may be allocated more
4775  * space than it requested.
4776  *
4777  * If the size request in a given direction is -1 (unset), then
4778  * the "natural" size request of the widget will be used instead.
4779  *
4780  * Widgets can't actually be allocated a size less than 1 by 1, but
4781  * you can pass 0,0 to this function to mean "as small as possible."
4782  **/
4783 void
4784 gtk_widget_set_size_request (GtkWidget *widget,
4785                              gint       width,
4786                              gint       height)
4787 {
4788   g_return_if_fail (GTK_IS_WIDGET (widget));
4789   g_return_if_fail (width >= -1);
4790   g_return_if_fail (height >= -1);
4791
4792   if (width == 0)
4793     width = 1;
4794   if (height == 0)
4795     height = 1;
4796   
4797   gtk_widget_set_usize (widget, width, height);
4798 }
4799
4800
4801 /**
4802  * gtk_widget_get_size_request:
4803  * @widget: a #GtkWidget
4804  * @width: return location for width, or %NULL
4805  * @height: return location for height, or %NULL
4806  *
4807  * Gets the size request that was explicitly set for the widget using
4808  * gtk_widget_set_size_request().  A value of -1 stored in @width or
4809  * @height indicates that that dimension has not been set explicitly
4810  * and the natural requisition of the widget will be used intead. See
4811  * gtk_widget_set_size_request(). To get the size a widget will
4812  * actually use, call gtk_widget_size_request() instead of
4813  * this function.
4814  * 
4815  **/
4816  
4817 void
4818 gtk_widget_get_size_request (GtkWidget *widget,
4819                              gint      *width,
4820                              gint      *height)
4821 {
4822   GtkWidgetAuxInfo *aux_info;
4823
4824   g_return_if_fail (GTK_IS_WIDGET (widget));
4825
4826   aux_info = _gtk_widget_get_aux_info (widget, FALSE);
4827
4828   if (width)
4829     *width = aux_info ? aux_info->width : -1;
4830
4831   if (height)
4832     *height = aux_info ? aux_info->height : -1;
4833 }
4834
4835 /**
4836  * gtk_widget_set_events:
4837  * @widget: a #GtkWidget
4838  * @events: event mask
4839  *
4840  * Sets the event mask (see #GdkEventMask) for a widget. The event
4841  * mask determines which events a widget will receive. Keep in mind
4842  * that different widgets have different default event masks, and by
4843  * changing the event mask you may disrupt a widget's functionality,
4844  * so be careful. This function must be called while a widget is
4845  * unrealized. Consider gtk_widget_add_events() for widgets that are
4846  * already realized, or if you want to preserve the existing event
4847  * mask. This function can't be used with #GTK_NO_WINDOW widgets;
4848  * to get events on those widgets, place them inside a #GtkEventBox
4849  * and receive events on the event box.
4850  * 
4851  **/
4852 void
4853 gtk_widget_set_events (GtkWidget *widget,
4854                        gint       events)
4855 {
4856   gint *eventp;
4857   
4858   g_return_if_fail (GTK_IS_WIDGET (widget));
4859   g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4860   
4861   eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
4862   
4863   if (events)
4864     {
4865       if (!eventp)
4866         eventp = g_new (gint, 1);
4867       
4868       *eventp = events;
4869       gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
4870     }
4871   else if (eventp)
4872     {
4873       g_free (eventp);
4874       gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
4875     }
4876
4877   g_object_notify (G_OBJECT (widget), "events");
4878 }
4879
4880 /**
4881  * gtk_widget_add_events:
4882  * @widget: a #GtkWidget
4883  * @events: an event mask, see #GdkEventMask
4884  *
4885  * Adds the events in the bitfield @events to the event mask for
4886  * @widget. See gtk_widget_set_events() for details.
4887  * 
4888  **/
4889 void
4890 gtk_widget_add_events (GtkWidget *widget,
4891                        gint       events)
4892 {
4893   gint *eventp;
4894   
4895   g_return_if_fail (GTK_IS_WIDGET (widget));
4896
4897   eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
4898   
4899   if (events)
4900     {
4901       if (!eventp)
4902         {
4903           eventp = g_new (gint, 1);
4904           *eventp = 0;
4905         }
4906       
4907       *eventp |= events;
4908       gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
4909     }
4910   else if (eventp)
4911     {
4912       g_free (eventp);
4913       gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
4914     }
4915
4916   if (GTK_WIDGET_REALIZED (widget))
4917     {
4918       if (GTK_WIDGET_NO_WINDOW (widget))
4919         {
4920           GList *children = gdk_window_get_children (widget->window);
4921           GList *tmp_list = children;
4922
4923           while (tmp_list)
4924             {
4925               GdkWindow *window = tmp_list->data;
4926               gpointer user_data;
4927
4928               gdk_window_get_user_data (window, &user_data);
4929               if (user_data == widget)
4930                 gdk_window_set_events (window, gdk_window_get_events (window) | events);
4931               tmp_list = tmp_list->next;
4932             }
4933
4934           g_list_free (children);
4935         }
4936       else
4937         {
4938           gdk_window_set_events (widget->window, gdk_window_get_events (widget->window) | events);
4939         }
4940     }
4941
4942   g_object_notify (G_OBJECT (widget), "events");
4943 }
4944
4945 /**
4946  * gtk_widget_set_extension_events:
4947  * @widget: a #GtkWidget
4948  * @mode: bitfield of extension events to receive
4949  *
4950  * Sets the extension events mask to @mode. See #GdkExtensionMode
4951  * and gdk_input_set_extension_events().
4952  * 
4953  **/
4954 void
4955 gtk_widget_set_extension_events (GtkWidget *widget,
4956                                  GdkExtensionMode mode)
4957 {
4958   GdkExtensionMode *modep;
4959   
4960   g_return_if_fail (GTK_IS_WIDGET (widget));
4961   
4962   modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
4963   
4964   if (!modep)
4965     modep = g_new (GdkExtensionMode, 1);
4966   
4967   *modep = mode;
4968   gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode, modep);
4969   g_object_notify (G_OBJECT (widget), "extension_events");
4970 }
4971
4972 /**
4973  * gtk_widget_get_toplevel:
4974  * @widget: a #GtkWidget
4975  * 
4976  * This function returns the topmost widget in the container hierarchy
4977  * @widget is a part of. If @widget has no parent widgets, it will be
4978  * returned as the topmost widget. No reference will be added to the
4979  * returned widget; it should not be unreferenced.
4980  *
4981  * Note the difference in behavior vs. gtk_widget_get_ancestor();
4982  * <literal>gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)</literal> 
4983  * would return
4984  * %NULL if @widget wasn't inside a toplevel window, and if the
4985  * window was inside a #GtkWindow-derived widget which was in turn
4986  * inside the toplevel #GtkWindow. While the second case may
4987  * seem unlikely, it actually happens when a #GtkPlug is embedded
4988  * inside a #GtkSocket within the same application.
4989  * 
4990  * To reliably find the toplevel #GtkWindow, use
4991  * gtk_widget_get_toplevel() and check if the %TOPLEVEL flags
4992  * is set on the result.
4993  *  <informalexample><programlisting>
4994  *  <!>GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
4995  *  <!>if (GTK_WIDGET_TOPLEVEL (toplevel))
4996  *  <!> {
4997  *  <!>   [ Perform action on toplevel. ]
4998  *  <!> }
4999  *  </programlisting></informalexample>
5000  *
5001  * Return value: the topmost ancestor of @widget, or @widget itself if there's no ancestor.
5002  **/
5003 GtkWidget*
5004 gtk_widget_get_toplevel (GtkWidget *widget)
5005 {
5006   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5007   
5008   while (widget->parent)
5009     widget = widget->parent;
5010   
5011   return widget;
5012 }
5013
5014 /**
5015  * gtk_widget_get_ancestor:
5016  * @widget: a #GtkWidget
5017  * @widget_type: ancestor type
5018  * 
5019  * Gets the first ancestor of @widget with type @widget_type. For example,
5020  * <literal>gtk_widget_get_ancestor (widget, GTK_TYPE_BOX)</literal> gets the 
5021  * first #GtkBox that's
5022  * an ancestor of @widget. No reference will be added to the returned widget;
5023  * it should not be unreferenced. See note about checking for a toplevel
5024  * #GtkWindow in the docs for gtk_widget_get_toplevel().
5025  * 
5026  * Return value: the ancestor widget, or %NULL if not found
5027  **/
5028 GtkWidget*
5029 gtk_widget_get_ancestor (GtkWidget *widget,
5030                          GtkType    widget_type)
5031 {
5032   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5033   
5034   while (widget && !gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type))
5035     widget = widget->parent;
5036   
5037   if (!(widget && gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type)))
5038     return NULL;
5039   
5040   return widget;
5041 }
5042
5043 /**
5044  * gtk_widget_get_colormap:
5045  * @widget: a #GtkWidget
5046  * 
5047  * Gets the colormap that will be used to render @widget. No reference will
5048  * be added to the returned colormap; it should not be unreferenced.
5049  * 
5050  * Return value: the colormap used by @widget
5051  **/
5052 GdkColormap*
5053 gtk_widget_get_colormap (GtkWidget *widget)
5054 {
5055   GdkColormap *colormap;
5056   
5057   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5058   
5059   if (widget->window)
5060     {
5061       colormap = gdk_window_get_colormap (widget->window);
5062       /* If window was destroyed previously, we'll get NULL here */
5063       if (colormap)
5064         return colormap;
5065     }
5066
5067   while (widget)
5068     {
5069       colormap = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_colormap);
5070       if (colormap)
5071         return colormap;
5072
5073       widget = widget->parent;
5074     }
5075
5076   return gtk_widget_get_default_colormap ();
5077 }
5078
5079 /**
5080  * gtk_widget_get_visual:
5081  * @widget: a #GtkWidget
5082  * 
5083  * Gets the visual that will be used to render @widget.
5084  * 
5085  * Return value: the visual for @widget
5086  **/
5087 GdkVisual*
5088 gtk_widget_get_visual (GtkWidget *widget)
5089 {
5090   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5091
5092   return gdk_colormap_get_visual (gtk_widget_get_colormap (widget));
5093 }
5094
5095 /**
5096  * gtk_widget_get_settings:
5097  * @widget: a #GtkWidget
5098  * 
5099  * Gets the settings object holding the settings (global property
5100  * settings, RC file information, etc) used for this widget.
5101  * 
5102  * Return value: the relevant #GtkSettings object
5103  **/
5104 GtkSettings*
5105 gtk_widget_get_settings (GtkWidget *widget)
5106 {
5107   return gtk_settings_get_default ();
5108 }
5109
5110 /**
5111  * gtk_widget_set_colormap:
5112  * @widget: a #GtkWidget
5113  * @colormap: a colormap
5114  *
5115  * Sets the colormap for the widget to the given value. Widget must not
5116  * have been previously realized. This probably should only be used
5117  * from an <function>init()</function> function (i.e. from the constructor 
5118  * for the widget).
5119  * 
5120  **/
5121 void
5122 gtk_widget_set_colormap (GtkWidget   *widget,
5123                          GdkColormap *colormap)
5124 {
5125   g_return_if_fail (GTK_IS_WIDGET (widget));
5126   g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
5127   g_return_if_fail (GDK_IS_COLORMAP (colormap));
5128
5129   g_object_ref (G_OBJECT (colormap));
5130   
5131   g_object_set_qdata_full (G_OBJECT (widget), 
5132                            quark_colormap,
5133                            colormap,
5134                            (GtkDestroyNotify) g_object_unref);
5135 }
5136
5137 /**
5138  * gtk_widget_get_events:
5139  * @widget: a #GtkWidget
5140  * 
5141  * Returns the event mask for the widget (a bitfield containing flags
5142  * from the #GdkEventMask enumeration). These are the events that the widget
5143  * will receive.
5144  * 
5145  * Return value: event mask for @widget
5146  **/
5147 gint
5148 gtk_widget_get_events (GtkWidget *widget)
5149 {
5150   gint *events;
5151   
5152   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
5153   
5154   events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
5155   if (events)
5156     return *events;
5157   
5158   return 0;
5159 }
5160
5161 /**
5162  * gtk_widget_get_extension_events:
5163  * @widget: a #GtkWidget
5164  * 
5165  * Retrieves the extension events the widget will receive; see
5166  * gdk_input_set_extension_events().
5167  * 
5168  * Return value: extension events for @widget
5169  **/
5170 GdkExtensionMode
5171 gtk_widget_get_extension_events (GtkWidget *widget)
5172 {
5173   GdkExtensionMode *mode;
5174   
5175   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
5176   
5177   mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
5178   if (mode)
5179     return *mode;
5180   
5181   return 0;
5182 }
5183
5184 /**
5185  * gtk_widget_get_pointer:
5186  * @widget: a #GtkWidget
5187  * @x: return location for the X coordinate, or %NULL
5188  * @y: return location for the Y coordinate, or %NULL
5189  *
5190  * Obtains the location of the mouse pointer in widget coordinates.
5191  * Widget coordinates are a bit odd; for historical reasons, they are
5192  * defined as @widget->window coordinates for widgets that are not
5193  * #GTK_NO_WINDOW widgets, and are relative to @widget->allocation.x,
5194  * @widget->allocation.y for widgets that are #GTK_NO_WINDOW widgets.
5195  * 
5196  **/
5197 void
5198 gtk_widget_get_pointer (GtkWidget *widget,
5199                         gint      *x,
5200                         gint      *y)
5201 {
5202   g_return_if_fail (GTK_IS_WIDGET (widget));
5203   
5204   if (x)
5205     *x = -1;
5206   if (y)
5207     *y = -1;
5208   
5209   if (GTK_WIDGET_REALIZED (widget))
5210     {
5211       gdk_window_get_pointer (widget->window, x, y, NULL);
5212       
5213       if (GTK_WIDGET_NO_WINDOW (widget))
5214         {
5215           if (x)
5216             *x -= widget->allocation.x;
5217           if (y)
5218             *y -= widget->allocation.y;
5219         }
5220     }
5221 }
5222
5223 /**
5224  * gtk_widget_is_ancestor:
5225  * @widget: a #GtkWidget
5226  * @ancestor: another #GtkWidget
5227  * 
5228  * Determines whether @widget is somewhere inside @ancestor, possibly with
5229  * intermediate containers.
5230  * 
5231  * Return value: %TRUE if @ancestor contains @widget as a child, grandchild, great grandchild, etc.
5232  **/
5233 gboolean
5234 gtk_widget_is_ancestor (GtkWidget *widget,
5235                         GtkWidget *ancestor)
5236 {
5237   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
5238   g_return_val_if_fail (ancestor != NULL, FALSE);
5239   
5240   while (widget)
5241     {
5242       if (widget->parent == ancestor)
5243         return TRUE;
5244       widget = widget->parent;
5245     }
5246   
5247   return FALSE;
5248 }
5249
5250 static GQuark quark_composite_name = 0;
5251
5252 /**
5253  * gtk_widget_set_composite_name:
5254  * @widget: a #GtkWidget.
5255  * @name: the name to set.
5256  * 
5257  * Sets a widgets composite name. The widget must be
5258  * a composite child of its parent; see gtk_widget_push_composite_child().
5259  **/
5260 void
5261 gtk_widget_set_composite_name (GtkWidget   *widget,
5262                                const gchar *name)
5263 {
5264   g_return_if_fail (GTK_IS_WIDGET (widget));
5265   g_return_if_fail (GTK_WIDGET_COMPOSITE_CHILD (widget));
5266   g_return_if_fail (name != NULL);
5267
5268   if (!quark_composite_name)
5269     quark_composite_name = g_quark_from_static_string ("gtk-composite-name");
5270
5271   gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
5272                                   quark_composite_name,
5273                                   g_strdup (name),
5274                                   g_free);
5275 }
5276
5277 /**
5278  * gtk_widget_get_composite_name:
5279  * @widget: a #GtkWidget.
5280  * @returns: the composite name of @widget, or %NULL if @widget is not
5281  *   a composite child. The string should not be freed when it is no 
5282  *   longer needed.
5283  *
5284  * Obtains the composite name of a widget. 
5285  **/
5286 gchar*
5287 gtk_widget_get_composite_name (GtkWidget *widget)
5288 {
5289   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5290
5291   if (GTK_WIDGET_COMPOSITE_CHILD (widget) && widget->parent)
5292     return _gtk_container_child_composite_name (GTK_CONTAINER (widget->parent),
5293                                                widget);
5294   else
5295     return NULL;
5296 }
5297
5298 /**
5299  * gtk_widget_push_composite_child:
5300  * 
5301  * Makes all newly-created widgets as composite children until
5302  * the corresponding gtk_widget_pop_composite_child() call.
5303  * 
5304  * A composite child is a child that's an implementation detail of the
5305  * container it's inside and should not be visible to people using the
5306  * container. Composite children aren't treated differently by GTK (but
5307  * see gtk_container_foreach() vs. gtk_container_forall()), but e.g. GUI 
5308  * builders might want to treat them in a different way.
5309  * 
5310  * Here is a simple example:
5311  * <informalexample><programlisting>
5312  * <!>  gtk_widget_push_composite_child (<!>);
5313  * <!>  scrolled_window->hscrollbar = gtk_hscrollbar_new (hadjustment);
5314  * <!>  gtk_widget_set_composite_name (scrolled_window->hscrollbar, "hscrollbar");
5315  * <!>  gtk_widget_pop_composite_child (<!>);
5316  * <!>  gtk_widget_set_parent (scrolled_window->hscrollbar, 
5317  * <!>                         GTK_WIDGET (scrolled_window));
5318  * <!>  gtk_widget_ref (scrolled_window->hscrollbar);
5319  * </programlisting></informalexample>
5320  **/
5321 void
5322 gtk_widget_push_composite_child (void)
5323 {
5324   composite_child_stack++;
5325 }
5326
5327 /**
5328  * gtk_widget_pop_composite_child:
5329  *
5330  * Cancels the effect of a previous call to gtk_widget_push_composite_child().
5331  **/ 
5332 void
5333 gtk_widget_pop_composite_child (void)
5334 {
5335   if (composite_child_stack)
5336     composite_child_stack--;
5337 }
5338
5339 /**
5340  * gtk_widget_push_colormap:
5341  * @cmap: a #GdkColormap
5342  *
5343  * Pushes @cmap onto a global stack of colormaps; the topmost
5344  * colormap on the stack will be used to create all widgets.
5345  * Remove @cmap with gtk_widget_pop_colormap(). There's little
5346  * reason to use this function.
5347  * 
5348  **/
5349 void
5350 gtk_widget_push_colormap (GdkColormap *cmap)
5351 {
5352   g_return_if_fail (GDK_IS_COLORMAP (cmap));
5353
5354   colormap_stack = g_slist_prepend (colormap_stack, cmap);
5355 }
5356
5357 /**
5358  * gtk_widget_pop_colormap:
5359  *
5360  * Removes a colormap pushed with gtk_widget_push_colormap().
5361  * 
5362  **/
5363 void
5364 gtk_widget_pop_colormap (void)
5365 {
5366   if (colormap_stack)
5367     colormap_stack = g_slist_delete_link (colormap_stack, colormap_stack);
5368 }
5369
5370 /**
5371  * gtk_widget_set_default_colormap:
5372  * @colormap: a #GdkColormap
5373  * 
5374  * Sets the default colormap to use when creating widgets.
5375  * gtk_widget_push_colormap() is a better function to use if
5376  * you only want to affect a few widgets, rather than all widgets.
5377  * 
5378  **/
5379 void
5380 gtk_widget_set_default_colormap (GdkColormap *colormap)
5381 {
5382   g_return_if_fail (GDK_IS_COLORMAP (colormap));
5383
5384   if (default_colormap != colormap)
5385     {
5386       if (default_colormap)
5387         gdk_colormap_unref (default_colormap);
5388       default_colormap = colormap;
5389       if (default_colormap)
5390         gdk_colormap_ref (default_colormap);
5391     }
5392 }
5393
5394 /**
5395  * gtk_widget_get_default_colormap:
5396  * 
5397  * Obtains the default colormap used to create widgets.
5398  * 
5399  * Return value: default widget colormap
5400  **/
5401 GdkColormap*
5402 gtk_widget_get_default_colormap (void)
5403 {
5404   if (!default_colormap)
5405     gtk_widget_set_default_colormap (gdk_rgb_get_colormap ());
5406   
5407   return default_colormap;
5408 }
5409
5410 /**
5411  * gtk_widget_get_default_visual:
5412  * 
5413  * Obtains the visual of the default colormap. Not really useful;
5414  * used to be useful before gdk_colormap_get_visual() existed.
5415  * 
5416  * Return value: visual of the default colormap
5417  **/
5418 GdkVisual*
5419 gtk_widget_get_default_visual (void)
5420 {
5421   return gdk_colormap_get_visual (gtk_widget_get_default_colormap ());
5422 }
5423
5424 static void
5425 gtk_widget_emit_direction_changed (GtkWidget        *widget,
5426                                    GtkTextDirection  old_dir)
5427 {
5428   PangoContext *context = gtk_widget_peek_pango_context (widget);
5429
5430   if (context)
5431     pango_context_set_base_dir (context,
5432                                 gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
5433                                   PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
5434   
5435   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DIRECTION_CHANGED], old_dir);
5436 }
5437
5438 /**
5439  * gtk_widget_set_direction:
5440  * @widget: a #GtkWidget
5441  * @dir:    the new direction
5442  * 
5443  * Sets the reading direction on a particular widget. This direction
5444  * controls the primary direction for widgets containing text,
5445  * and also the direction in which the children of a container are
5446  * packed. The ability to set the direction is present in order
5447  * so that correct localization into languages with right-to-left
5448  * reading directions can be done. Generally, applications will
5449  * let the default reading direction present, except for containers
5450  * where the containers are arranged in an order that is explicitely
5451  * visual rather than logical (such as buttons for text justification).
5452  *
5453  * If the direction is set to %GTK_TEXT_DIR_NONE, then the value
5454  * set by gtk_widget_set_default_direction() will be used.
5455  **/
5456 void
5457 gtk_widget_set_direction (GtkWidget        *widget,
5458                           GtkTextDirection  dir)
5459 {
5460   GtkTextDirection old_dir;
5461   
5462   g_return_if_fail (GTK_IS_WIDGET (widget));
5463   g_return_if_fail (dir >= GTK_TEXT_DIR_NONE && dir <= GTK_TEXT_DIR_RTL);
5464
5465   old_dir = gtk_widget_get_direction (widget);
5466   
5467   if (dir == GTK_TEXT_DIR_NONE)
5468     GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_SET);
5469   else
5470     {
5471       GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_SET);
5472       if (dir == GTK_TEXT_DIR_LTR)
5473         GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_LTR);
5474       else
5475         GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_LTR);
5476     }
5477
5478   if (old_dir != gtk_widget_get_direction (widget))
5479     gtk_widget_emit_direction_changed (widget, old_dir);
5480 }
5481
5482 /**
5483  * gtk_widget_get_direction:
5484  * @widget: a #GtkWidget
5485  * 
5486  * Gets the reading direction for a particular widget. See
5487  * gtk_widget_set_direction().
5488  * 
5489  * Return value: the reading direction for the widget.
5490  **/
5491 GtkTextDirection
5492 gtk_widget_get_direction (GtkWidget *widget)
5493 {
5494   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_TEXT_DIR_LTR);
5495   
5496   if (GTK_WIDGET_DIRECTION_SET (widget))
5497     return GTK_WIDGET_DIRECTION_LTR (widget) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
5498   else
5499     return gtk_default_direction;
5500 }
5501
5502 static void
5503 gtk_widget_set_default_direction_recurse (GtkWidget *widget, gpointer data)
5504 {
5505   GtkTextDirection old_dir = GPOINTER_TO_UINT (data);
5506
5507   g_object_ref (G_OBJECT (widget));
5508   
5509   if (!GTK_WIDGET_DIRECTION_SET (widget))
5510     gtk_widget_emit_direction_changed (widget, old_dir);
5511   
5512   if (GTK_IS_CONTAINER (widget))
5513     gtk_container_forall (GTK_CONTAINER (widget),
5514                           gtk_widget_set_default_direction_recurse,
5515                           data);
5516
5517   g_object_unref (G_OBJECT (widget));
5518 }
5519
5520 /**
5521  * gtk_widget_set_default_direction:
5522  * @dir: the new default direction. This cannot be
5523  *        %GTK_TEXT_DIR_NONE.
5524  * 
5525  * Sets the default reading direction for widgets where the
5526  * direction has not been explicitly set by gtk_widget_set_direction().
5527  **/
5528 void
5529 gtk_widget_set_default_direction (GtkTextDirection dir)
5530 {
5531   g_return_if_fail (dir == GTK_TEXT_DIR_RTL || dir == GTK_TEXT_DIR_LTR);
5532
5533   if (dir != gtk_default_direction)
5534     {
5535       GList *toplevels, *tmp_list;
5536       GtkTextDirection old_dir = gtk_default_direction;
5537       
5538       gtk_default_direction = dir;
5539
5540       tmp_list = toplevels = gtk_window_list_toplevels ();
5541       g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
5542       
5543       while (tmp_list)
5544         {
5545           gtk_widget_set_default_direction_recurse (tmp_list->data,
5546                                                     GUINT_TO_POINTER (old_dir));
5547           g_object_unref (tmp_list->data);
5548           tmp_list = tmp_list->next;
5549         }
5550
5551       g_list_free (toplevels);
5552     }
5553 }
5554
5555 /**
5556  * gtk_widget_get_default_direction:
5557  * 
5558  * Obtains the current default reading direction. See
5559  * gtk_widget_set_default_direction().
5560  *
5561  * Return value: the current default direction. 
5562  **/
5563 GtkTextDirection
5564 gtk_widget_get_default_direction (void)
5565 {
5566   return gtk_default_direction;
5567 }
5568
5569 static void
5570 gtk_widget_dispose (GObject *object)
5571 {
5572   GtkWidget *widget = GTK_WIDGET (object);
5573
5574   if (widget->parent)
5575     gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
5576
5577   GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
5578   if (GTK_WIDGET_REALIZED (widget))
5579     gtk_widget_unrealize (widget);
5580   
5581   G_OBJECT_CLASS (parent_class)->dispose (object);
5582 }
5583
5584 static void
5585 gtk_widget_real_destroy (GtkObject *object)
5586 {
5587   /* gtk_object_destroy() will already hold a refcount on object */
5588   GtkWidget *widget = GTK_WIDGET (object);
5589
5590   /* wipe accelerator closures (keep order) */
5591   g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
5592   g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
5593
5594   gtk_grab_remove (widget);
5595   
5596   g_object_unref (widget->style);
5597   widget->style = gtk_widget_get_default_style ();
5598   g_object_ref (widget->style);
5599
5600   GTK_OBJECT_CLASS (parent_class)->destroy (object);
5601 }
5602
5603 static void
5604 gtk_widget_finalize (GObject *object)
5605 {
5606   GtkWidget *widget = GTK_WIDGET (object);
5607   GtkWidgetAuxInfo *aux_info;
5608   gint *events;
5609   GdkExtensionMode *mode;
5610   GtkAccessible *accessible;
5611   
5612   gtk_grab_remove (widget);
5613
5614   g_object_unref (widget->style);
5615   widget->style = NULL;
5616
5617   if (widget->name)
5618     g_free (widget->name);
5619   
5620   aux_info =_gtk_widget_get_aux_info (widget, FALSE);
5621   if (aux_info)
5622     gtk_widget_aux_info_destroy (aux_info);
5623   
5624   events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
5625   if (events)
5626     g_free (events);
5627   
5628   mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
5629   if (mode)
5630     g_free (mode);
5631
5632   accessible = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_accessible_object);
5633   if (accessible)
5634     g_object_unref (G_OBJECT (accessible));
5635
5636   G_OBJECT_CLASS (parent_class)->finalize (object);
5637 }
5638
5639 /*****************************************
5640  * gtk_widget_real_map:
5641  *
5642  *   arguments:
5643  *
5644  *   results:
5645  *****************************************/
5646
5647 static void
5648 gtk_widget_real_map (GtkWidget *widget)
5649 {
5650   g_return_if_fail (GTK_WIDGET_REALIZED (widget) == TRUE);
5651   
5652   if (!GTK_WIDGET_MAPPED (widget))
5653     {
5654       GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
5655       
5656       if (!GTK_WIDGET_NO_WINDOW (widget))
5657         gdk_window_show (widget->window);
5658     }
5659 }
5660
5661 /*****************************************
5662  * gtk_widget_real_unmap:
5663  *
5664  *   arguments:
5665  *
5666  *   results:
5667  *****************************************/
5668
5669 static void
5670 gtk_widget_real_unmap (GtkWidget *widget)
5671 {
5672   if (GTK_WIDGET_MAPPED (widget))
5673     {
5674       GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
5675
5676       if (!GTK_WIDGET_NO_WINDOW (widget))
5677         gdk_window_hide (widget->window);
5678     }
5679 }
5680
5681 /*****************************************
5682  * gtk_widget_real_realize:
5683  *
5684  *   arguments:
5685  *
5686  *   results:
5687  *****************************************/
5688
5689 static void
5690 gtk_widget_real_realize (GtkWidget *widget)
5691 {
5692   g_return_if_fail (GTK_WIDGET_NO_WINDOW (widget));
5693   
5694   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
5695   if (widget->parent)
5696     {
5697       widget->window = gtk_widget_get_parent_window (widget);
5698       gdk_window_ref (widget->window);
5699     }
5700   widget->style = gtk_style_attach (widget->style, widget->window);
5701 }
5702
5703 /*****************************************
5704  * gtk_widget_real_unrealize:
5705  *
5706  *   arguments:
5707  *
5708  *   results:
5709  *****************************************/
5710
5711 static void
5712 gtk_widget_real_unrealize (GtkWidget *widget)
5713 {
5714   if (GTK_WIDGET_MAPPED (widget))
5715     gtk_widget_real_unmap (widget);
5716
5717   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
5718
5719   /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT (widget)->klass->type));
5720    */
5721
5722    /* We must do unrealize child widget BEFORE container widget.
5723     * gdk_window_destroy() destroys specified xwindow and its sub-xwindows.
5724     * So, unrealizing container widget bofore its children causes the problem 
5725     * (for example, gdk_ic_destroy () with destroyed window causes crash. )
5726     */
5727
5728   if (GTK_IS_CONTAINER (widget))
5729     gtk_container_forall (GTK_CONTAINER (widget),
5730                           (GtkCallback) gtk_widget_unrealize,
5731                           NULL);
5732
5733   gtk_style_detach (widget->style);
5734   if (!GTK_WIDGET_NO_WINDOW (widget))
5735     {
5736       gdk_window_set_user_data (widget->window, NULL);
5737       gdk_window_destroy (widget->window);
5738       widget->window = NULL;
5739     }
5740   else
5741     {
5742       gdk_window_unref (widget->window);
5743       widget->window = NULL;
5744     }
5745
5746   gtk_selection_remove_all (widget);
5747   
5748   GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
5749 }
5750
5751 static void
5752 gtk_widget_real_size_request (GtkWidget         *widget,
5753                               GtkRequisition    *requisition)
5754 {
5755   requisition->width = widget->requisition.width;
5756   requisition->height = widget->requisition.height;
5757 }
5758
5759 /**
5760  * _gtk_widget_peek_colormap:
5761  * 
5762  * Returns colormap currently pushed by gtk_widget_push_colormap, if any.
5763  * 
5764  * Return value: the currently pushed colormap, or %NULL if there is none.
5765  **/
5766 GdkColormap*
5767 _gtk_widget_peek_colormap (void)
5768 {
5769   if (colormap_stack)
5770     return (GdkColormap*) colormap_stack->data;
5771   return NULL;
5772 }
5773
5774 static void
5775 gtk_widget_propagate_state (GtkWidget           *widget,
5776                             GtkStateData        *data)
5777 {
5778   guint8 old_state;
5779
5780   /* don't call this function with state==GTK_STATE_INSENSITIVE,
5781    * parent_sensitive==TRUE on a sensitive widget
5782    */
5783
5784   old_state = GTK_WIDGET_STATE (widget);
5785
5786   if (data->parent_sensitive)
5787     {
5788       GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
5789
5790       if (GTK_WIDGET_IS_SENSITIVE (widget))
5791         {
5792           if (data->state_restoration)
5793             GTK_WIDGET_STATE (widget) = GTK_WIDGET_SAVED_STATE (widget);
5794           else
5795             GTK_WIDGET_STATE (widget) = data->state;
5796         }
5797       else
5798         {
5799           GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
5800           if (!data->state_restoration &&
5801               data->state != GTK_STATE_INSENSITIVE)
5802             GTK_WIDGET_SAVED_STATE (widget) = data->state;
5803         }
5804     }
5805   else
5806     {
5807       GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
5808       if (!data->state_restoration)
5809         {
5810           if (data->state != GTK_STATE_INSENSITIVE)
5811             GTK_WIDGET_SAVED_STATE (widget) = data->state;
5812         }
5813       else if (GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE)
5814         GTK_WIDGET_SAVED_STATE (widget) = GTK_WIDGET_STATE (widget);
5815       GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
5816     }
5817
5818   if (gtk_widget_is_focus (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
5819     {
5820       GtkWidget *window;
5821
5822       window = gtk_widget_get_toplevel (widget);
5823       if (window && GTK_WIDGET_TOPLEVEL (window))
5824         gtk_window_set_focus (GTK_WINDOW (window), NULL);
5825     }
5826
5827   if (old_state != GTK_WIDGET_STATE (widget))
5828     {
5829       gtk_widget_ref (widget);
5830       
5831       if (!GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_HAS_GRAB (widget))
5832         gtk_grab_remove (widget);
5833       
5834       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state);
5835       
5836       
5837       if (GTK_IS_CONTAINER (widget))
5838         {
5839           data->parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget) != FALSE);
5840           data->state = GTK_WIDGET_STATE (widget);
5841           if (data->use_forall)
5842             gtk_container_forall (GTK_CONTAINER (widget),
5843                                   (GtkCallback) gtk_widget_propagate_state,
5844                                   data);
5845           else
5846             gtk_container_foreach (GTK_CONTAINER (widget),
5847                                    (GtkCallback) gtk_widget_propagate_state,
5848                                    data);
5849         }
5850       gtk_widget_unref (widget);
5851     }
5852 }
5853
5854 /**
5855  * _gtk_widget_get_aux_info:
5856  * @widget: a #GtkWidget
5857  * @create: if %TRUE, create the structure if it doesn't exist
5858  * 
5859  * Get the #GtkWidgetAuxInfo structure for the widget.
5860  * 
5861  * Return value: the #GtkAuxInfo structure for the widget, or
5862  *    %NULL if @create is %FALSE and one doesn't already exist.
5863  **/
5864 GtkWidgetAuxInfo*
5865 _gtk_widget_get_aux_info (GtkWidget *widget,
5866                           gboolean   create)
5867 {
5868   GtkWidgetAuxInfo *aux_info;
5869   
5870   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
5871   if (!aux_info && create)
5872     {
5873       if (!aux_info_mem_chunk)
5874         aux_info_mem_chunk = g_mem_chunk_new ("widget aux info mem chunk",
5875                                               sizeof (GtkWidgetAuxInfo),
5876                                               1024, G_ALLOC_AND_FREE);
5877       aux_info = g_chunk_new (GtkWidgetAuxInfo, aux_info_mem_chunk);
5878
5879       aux_info->width = -1;
5880       aux_info->height = -1;
5881       aux_info->x = 0;
5882       aux_info->y = 0;
5883       aux_info->x_set = FALSE;
5884       aux_info->y_set = FALSE;
5885       gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
5886     }
5887   
5888   return aux_info;
5889 }
5890
5891 /*****************************************
5892  * gtk_widget_aux_info_destroy:
5893  *
5894  *   arguments:
5895  *
5896  *   results:
5897  *****************************************/
5898
5899 static void
5900 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
5901 {
5902   g_mem_chunk_free (aux_info_mem_chunk, aux_info);
5903 }
5904
5905 static void
5906 gtk_widget_shape_info_destroy (GtkWidgetShapeInfo *info)
5907 {
5908   gdk_drawable_unref (info->shape_mask);
5909   g_free (info);
5910 }
5911
5912 /**
5913  * gtk_widget_shape_combine_mask: 
5914  * @widget: a #GtkWidget.
5915  * @shape_mask: shape to be added, or %NULL to remove an existing shape. 
5916  * @offset_x: X position of shape mask with respect to @window.
5917  * @offset_y: Y position of shape mask with respect to @window.
5918  * 
5919  * Sets a shape for this widget's GDK window. This allows for
5920  * transparent windows etc., see gdk_window_shape_combine_mask()
5921  * for more information.
5922  **/
5923 void
5924 gtk_widget_shape_combine_mask (GtkWidget *widget,
5925                                GdkBitmap *shape_mask,
5926                                gint       offset_x,
5927                                gint       offset_y)
5928 {
5929   GtkWidgetShapeInfo* shape_info;
5930   
5931   g_return_if_fail (GTK_IS_WIDGET (widget));
5932   /*  set_shape doesn't work on widgets without gdk window */
5933   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
5934
5935   if (!shape_mask)
5936     {
5937       GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
5938       
5939       if (widget->window)
5940         gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
5941       
5942       g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
5943     }
5944   else
5945     {
5946       GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
5947       
5948       shape_info = g_new (GtkWidgetShapeInfo, 1);
5949       g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info, shape_info,
5950                                (GDestroyNotify) gtk_widget_shape_info_destroy);
5951       
5952       shape_info->shape_mask = gdk_drawable_ref (shape_mask);
5953       shape_info->offset_x = offset_x;
5954       shape_info->offset_y = offset_y;
5955       
5956       /* set shape if widget has a gdk window allready.
5957        * otherwise the shape is scheduled to be set by gtk_widget_realize.
5958        */
5959       if (widget->window)
5960         gdk_window_shape_combine_mask (widget->window, shape_mask,
5961                                        offset_x, offset_y);
5962     }
5963 }
5964
5965 static void
5966 gtk_reset_shapes_recurse (GtkWidget *widget,
5967                           GdkWindow *window)
5968 {
5969   gpointer data;
5970   GList *list;
5971
5972   gdk_window_get_user_data (window, &data);
5973   if (data != widget)
5974     return;
5975
5976   gdk_window_shape_combine_mask (window, NULL, 0, 0);
5977   for (list = gdk_window_peek_children (window); list; list = list->next)
5978     gtk_reset_shapes_recurse (widget, list->data);
5979 }
5980
5981 /**
5982  * gtk_widget_reset_shapes:
5983  * @widget: a #GtkWidget.
5984  *
5985  * Recursively resets the shape on this widget and its descendants.
5986  **/
5987 void
5988 gtk_widget_reset_shapes (GtkWidget *widget)
5989 {
5990   g_return_if_fail (GTK_IS_WIDGET (widget));
5991   g_return_if_fail (GTK_WIDGET_REALIZED (widget));
5992
5993   if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
5994     gtk_reset_shapes_recurse (widget, widget->window);
5995 }
5996
5997 /**
5998  * gtk_widget_ref:
5999  * @widget: a #GtkWidget
6000  * 
6001  * Adds a reference to a widget. This function is exactly the same
6002  * as calling g_object_ref(), and exists mostly for historical
6003  * reasons. It can still be convenient to avoid casting a widget
6004  * to a #GObject, it saves a small amount of typing.
6005  * 
6006  * Return value: the widget that was referenced
6007  **/
6008 GtkWidget*
6009 gtk_widget_ref (GtkWidget *widget)
6010 {
6011   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6012
6013   return (GtkWidget*) g_object_ref ((GObject*) widget);
6014 }
6015
6016 /**
6017  * gtk_widget_unref:
6018  * @widget: a #GtkWidget
6019  *
6020  * Inverse of gtk_widget_ref(). Equivalent to g_object_unref().
6021  * 
6022  **/
6023 void
6024 gtk_widget_unref (GtkWidget *widget)
6025 {
6026   g_return_if_fail (GTK_IS_WIDGET (widget));
6027
6028   g_object_unref ((GObject*) widget);
6029 }
6030
6031
6032 /* style properties
6033  */
6034
6035 void
6036 gtk_widget_class_install_style_property_parser (GtkWidgetClass     *class,
6037                                                 GParamSpec         *pspec,
6038                                                 GtkRcPropertyParser parser)
6039 {
6040   g_return_if_fail (GTK_IS_WIDGET_CLASS (class));
6041   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
6042   g_return_if_fail (pspec->flags & G_PARAM_READABLE);
6043   g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT)));
6044   
6045   if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE))
6046     {
6047       g_warning (G_STRLOC ": class `%s' already contains a style property named `%s'",
6048                  G_OBJECT_CLASS_NAME (class),
6049                  pspec->name);
6050       return;
6051     }
6052
6053   g_param_spec_ref (pspec);
6054   g_param_spec_sink (pspec);
6055   g_param_spec_set_qdata (pspec, quark_property_parser, parser);
6056   g_param_spec_pool_insert (style_property_spec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
6057 }
6058
6059 void
6060 gtk_widget_class_install_style_property (GtkWidgetClass *class,
6061                                          GParamSpec     *pspec)
6062 {
6063   GtkRcPropertyParser parser;
6064
6065   g_return_if_fail (GTK_IS_WIDGET_CLASS (class));
6066   g_return_if_fail (G_IS_PARAM_SPEC (pspec));
6067
6068   parser = _gtk_rc_property_parser_from_type (G_PARAM_SPEC_VALUE_TYPE (pspec));
6069
6070   gtk_widget_class_install_style_property_parser (class, pspec, parser);
6071 }
6072
6073 /**
6074  * gtk_widget_style_get_property:
6075  * @widget: a #GtkWidget
6076  * @property_name: the name of a style property
6077  * @value: location to return the property value 
6078  *
6079  * Gets the value of a style property of @widget.
6080  */
6081 void
6082 gtk_widget_style_get_property (GtkWidget   *widget,
6083                                const gchar *property_name,
6084                                GValue      *value)
6085 {
6086   GParamSpec *pspec;
6087
6088   g_return_if_fail (GTK_IS_WIDGET (widget));
6089   g_return_if_fail (property_name != NULL);
6090   g_return_if_fail (G_IS_VALUE (value));
6091
6092   g_object_ref (widget);
6093   pspec = g_param_spec_pool_lookup (style_property_spec_pool,
6094                                     property_name,
6095                                     G_OBJECT_TYPE (widget),
6096                                     TRUE);
6097   if (!pspec)
6098     g_warning ("%s: widget class `%s' has no property named `%s'",
6099                G_STRLOC,
6100                G_OBJECT_TYPE_NAME (widget),
6101                property_name);
6102   else
6103     {
6104       const GValue *peek_value;
6105
6106       peek_value = _gtk_style_peek_property_value (widget->style,
6107                                                    G_OBJECT_TYPE (widget),
6108                                                    pspec,
6109                                                    g_param_spec_get_qdata (pspec, quark_property_parser));
6110       
6111       /* auto-conversion of the caller's value type
6112        */
6113       if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
6114         g_value_copy (peek_value, value);
6115       else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
6116         g_value_transform (peek_value, value);
6117       else
6118         g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
6119                    pspec->name,
6120                    g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
6121                    G_VALUE_TYPE_NAME (value));
6122     }
6123   g_object_unref (widget);
6124 }
6125
6126 /**
6127  * gtk_widget_style_get_valist:
6128  * @widget: a #GtkWidget
6129  * @first_property_name: the name of the first property to get
6130  * @var_args: a <type>va_list</type> of pairs of property names and
6131  *     locations to return the property values, starting with the location
6132  *     for @first_property_name.
6133  * 
6134  * Non-vararg variant of gtk_widget_style_get(). Used primarily by language 
6135  * bindings.
6136  */ 
6137 void
6138 gtk_widget_style_get_valist (GtkWidget   *widget,
6139                              const gchar *first_property_name,
6140                              va_list      var_args)
6141 {
6142   const gchar *name;
6143
6144   g_return_if_fail (GTK_IS_WIDGET (widget));
6145
6146   g_object_ref (widget);
6147
6148   name = first_property_name;
6149   while (name)
6150     {
6151       const GValue *peek_value;
6152       GParamSpec *pspec;
6153       gchar *error;
6154
6155       pspec = g_param_spec_pool_lookup (style_property_spec_pool,
6156                                         name,
6157                                         G_OBJECT_TYPE (widget),
6158                                         TRUE);
6159       if (!pspec)
6160         {
6161           g_warning ("%s: widget class `%s' has no property named `%s'",
6162                      G_STRLOC,
6163                      G_OBJECT_TYPE_NAME (widget),
6164                      name);
6165           break;
6166         }
6167       /* style pspecs are always readable so we can spare that check here */
6168
6169       peek_value = _gtk_style_peek_property_value (widget->style,
6170                                                    G_OBJECT_TYPE (widget),
6171                                                    pspec,
6172                                                    g_param_spec_get_qdata (pspec, quark_property_parser));
6173       G_VALUE_LCOPY (peek_value, var_args, 0, &error);
6174       if (error)
6175         {
6176           g_warning ("%s: %s", G_STRLOC, error);
6177           g_free (error);
6178           break;
6179         }
6180
6181       name = va_arg (var_args, gchar*);
6182     }
6183
6184   g_object_unref (widget);
6185 }
6186
6187 /**
6188  * gtk_widget_style_get:
6189  * @widget: a #GtkWidget
6190  * @first_property_name: the name of the first property to get
6191  * @Varargs: pairs of property names and locations to 
6192  *   return the property values, starting with the location for 
6193  *   @first_property_name, terminated by %NULL.
6194  *
6195  * Gets the values of a multiple style properties of @widget.
6196  */
6197 void
6198 gtk_widget_style_get (GtkWidget   *widget,
6199                       const gchar *first_property_name,
6200                       ...)
6201 {
6202   va_list var_args;
6203
6204   g_return_if_fail (GTK_IS_WIDGET (widget));
6205
6206   va_start (var_args, first_property_name);
6207   gtk_widget_style_get_valist (widget, first_property_name, var_args);
6208   va_end (var_args);
6209 }
6210
6211 /**
6212  * gtk_widget_path:
6213  * @widget: a #GtkWidget
6214  * @path_length: location to store length of the path, or %NULL
6215  * @path: location to store allocated path string, or %NULL 
6216  * @path_reversed: location to store allocated reverse path string, or %NULL
6217  *
6218  * Obtains the full path to @widget. The path is simply the name of a
6219  * widget and all its parents in the container hierarchy, separated by
6220  * periods. The name of a widget comes from
6221  * gtk_widget_get_name(). Paths are used to apply styles to a widget
6222  * in gtkrc configuration files.  Widget names are the type of the
6223  * widget by default (e.g. "GtkButton") or can be set to an
6224  * application-specific value with gtk_widget_set_name().  By setting
6225  * the name of a widget, you allow users or theme authors to apply
6226  * styles to that specific widget in their gtkrc
6227  * file. @path_reversed_p fills in the path in reverse order,
6228  * i.e. starting with @widget's name instead of starting with the name
6229  * of @widget's outermost ancestor.
6230  * 
6231  **/
6232 void
6233 gtk_widget_path (GtkWidget *widget,
6234                  guint     *path_length,
6235                  gchar    **path,
6236                  gchar    **path_reversed)
6237 {
6238   static gchar *rev_path = NULL;
6239   static guint tmp_path_len = 0;
6240   guint len;
6241   
6242   g_return_if_fail (GTK_IS_WIDGET (widget));
6243   
6244   len = 0;
6245   do
6246     {
6247       const gchar *string;
6248       const gchar *s;
6249       gchar *d;
6250       guint l;
6251       
6252       string = gtk_widget_get_name (widget);
6253       l = strlen (string);
6254       while (tmp_path_len <= len + l + 1)
6255         {
6256           tmp_path_len += INIT_PATH_SIZE;
6257           rev_path = g_realloc (rev_path, tmp_path_len);
6258         }
6259       s = string + l - 1;
6260       d = rev_path + len;
6261       while (s >= string)
6262         *(d++) = *(s--);
6263       len += l;
6264       
6265       widget = widget->parent;
6266       
6267       if (widget)
6268         rev_path[len++] = '.';
6269       else
6270         rev_path[len++] = 0;
6271     }
6272   while (widget);
6273   
6274   if (path_length)
6275     *path_length = len - 1;
6276   if (path_reversed)
6277     *path_reversed = g_strdup (rev_path);
6278   if (path)
6279     {
6280       *path = g_strdup (rev_path);
6281       g_strreverse (*path);
6282     }
6283 }
6284
6285 /**
6286  * gtk_widget_class_path:
6287  * @widget: a #GtkWidget
6288  * @path_length: location to store the length of the class path, or %NULL
6289  * @path: location to store the class path as an allocated string, or %NULL
6290  * @path_reversed: location to store the reverse class path as an allocated string, or %NULL
6291  *
6292  * Same as gtk_widget_path(), but always uses the name of a widget's type,
6293  * never uses a custom name set with gtk_widget_set_name().
6294  * 
6295  **/
6296 void
6297 gtk_widget_class_path (GtkWidget *widget,
6298                        guint     *path_length,
6299                        gchar    **path,
6300                        gchar    **path_reversed)
6301 {
6302   static gchar *rev_path = NULL;
6303   static guint tmp_path_len = 0;
6304   guint len;
6305   
6306   g_return_if_fail (GTK_IS_WIDGET (widget));
6307   
6308   len = 0;
6309   do
6310     {
6311       const gchar *string;
6312       const gchar *s;
6313       gchar *d;
6314       guint l;
6315       
6316       string = gtk_type_name (GTK_WIDGET_TYPE (widget));
6317       l = strlen (string);
6318       while (tmp_path_len <= len + l + 1)
6319         {
6320           tmp_path_len += INIT_PATH_SIZE;
6321           rev_path = g_realloc (rev_path, tmp_path_len);
6322         }
6323       s = string + l - 1;
6324       d = rev_path + len;
6325       while (s >= string)
6326         *(d++) = *(s--);
6327       len += l;
6328       
6329       widget = widget->parent;
6330       
6331       if (widget)
6332         rev_path[len++] = '.';
6333       else
6334         rev_path[len++] = 0;
6335     }
6336   while (widget);
6337   
6338   if (path_length)
6339     *path_length = len - 1;
6340   if (path_reversed)
6341     *path_reversed = g_strdup (rev_path);
6342   if (path)
6343     {
6344       *path = g_strdup (rev_path);
6345       g_strreverse (*path);
6346     }
6347 }
6348
6349 /**
6350  * gtk_requisition_copy:
6351  * @requisition: a #GtkRequisition.
6352  * @returns: a copy of @requisition.
6353  *
6354  * Copies a #GtkRequisition.
6355  **/
6356 GtkRequisition *
6357 gtk_requisition_copy (const GtkRequisition *requisition)
6358 {
6359   return (GtkRequisition *)g_memdup (requisition, sizeof (GtkRequisition));
6360 }
6361
6362 /**
6363  * gtk_requisition_free:
6364  * @requisition: a #GtkRequisition.
6365  * 
6366  * Frees a #GtkRequisition.
6367  **/
6368 void
6369 gtk_requisition_free (GtkRequisition *requisition)
6370 {
6371   g_free (requisition);
6372 }
6373
6374 AtkObject* 
6375 gtk_widget_get_accessible (GtkWidget *widget)
6376 {
6377   GtkWidgetClass *klass;
6378
6379   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6380
6381   klass = GTK_WIDGET_GET_CLASS (widget);
6382
6383   g_return_val_if_fail (klass->get_accessible != NULL, NULL);
6384
6385   return klass->get_accessible (widget);
6386 }
6387
6388 static AtkObject* 
6389 gtk_widget_real_get_accessible (GtkWidget *widget)
6390 {
6391   AtkObject* accessible;
6392
6393   accessible = g_object_get_qdata (G_OBJECT (widget), 
6394                                    quark_accessible_object);
6395   if (!accessible)
6396   {
6397     AtkObjectFactory *factory;
6398     AtkRegistry *default_registry;
6399
6400     default_registry = atk_get_default_registry ();
6401     factory = atk_registry_get_factory (default_registry, 
6402                                         GTK_OBJECT_TYPE (widget));
6403     accessible =
6404       atk_object_factory_create_accessible (factory,
6405                                             G_OBJECT (widget));
6406     g_object_set_qdata (G_OBJECT (widget), 
6407                         quark_accessible_object,
6408                         accessible);
6409   }
6410   return accessible;
6411 }
6412
6413 /*
6414  * Initialize a AtkImplementorIface instance's virtual pointers as
6415  * appropriate to this implementor's class (GtkWidget).
6416  */
6417 static void
6418 gtk_widget_accessible_interface_init (AtkImplementorIface *iface)
6419 {
6420   iface->ref_accessible = gtk_widget_ref_accessible;
6421 }
6422
6423 static AtkObject*
6424 gtk_widget_ref_accessible (AtkImplementor *implementor)
6425 {
6426   AtkObject *accessible;
6427
6428   accessible = gtk_widget_get_accessible (GTK_WIDGET (implementor));
6429   if (accessible)
6430     g_object_ref (G_OBJECT (accessible));
6431   return accessible;
6432 }
6433