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