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