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