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