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