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