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