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