]> Pileus Git - ~andy/gtk/blob - gtk/gtkwidget.c
urg, removed implementation of gtk_marshal_VOID__INT_INT_INT_INT. if
[~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
43
44 #define WIDGET_CLASS(w)  GTK_WIDGET_GET_CLASS (w)
45 #define INIT_PATH_SIZE  (512)
46
47
48 enum {
49   SHOW,
50   HIDE,
51   MAP,
52   UNMAP,
53   REALIZE,
54   UNREALIZE,
55   DRAW,
56   DRAW_FOCUS,
57   DRAW_DEFAULT,
58   SIZE_REQUEST,
59   SIZE_ALLOCATE,
60   STATE_CHANGED,
61   PARENT_SET,
62   STYLE_SET,
63   DIRECTION_CHANGED,
64   ADD_ACCELERATOR,
65   REMOVE_ACCELERATOR,
66   GRAB_FOCUS,
67   EVENT,
68   BUTTON_PRESS_EVENT,
69   BUTTON_RELEASE_EVENT,
70   SCROLL_EVENT,
71   MOTION_NOTIFY_EVENT,
72   DELETE_EVENT,
73   DESTROY_EVENT,
74   EXPOSE_EVENT,
75   KEY_PRESS_EVENT,
76   KEY_RELEASE_EVENT,
77   ENTER_NOTIFY_EVENT,
78   LEAVE_NOTIFY_EVENT,
79   CONFIGURE_EVENT,
80   FOCUS_IN_EVENT,
81   FOCUS_OUT_EVENT,
82   MAP_EVENT,
83   UNMAP_EVENT,
84   PROPERTY_NOTIFY_EVENT,
85   SELECTION_CLEAR_EVENT,
86   SELECTION_REQUEST_EVENT,
87   SELECTION_NOTIFY_EVENT,
88   SELECTION_GET,
89   SELECTION_RECEIVED,
90   PROXIMITY_IN_EVENT,
91   PROXIMITY_OUT_EVENT,
92   DRAG_BEGIN,
93   DRAG_END,
94   DRAG_DATA_DELETE,
95   DRAG_LEAVE,
96   DRAG_MOTION,
97   DRAG_DROP,
98   DRAG_DATA_GET,
99   DRAG_DATA_RECEIVED,
100   CLIENT_EVENT,
101   NO_EXPOSE_EVENT,
102   VISIBILITY_NOTIFY_EVENT,
103   DEBUG_MSG,
104   LAST_SIGNAL
105 };
106
107 enum {
108   ARG_0,
109   ARG_NAME,
110   ARG_PARENT,
111   ARG_X,
112   ARG_Y,
113   ARG_WIDTH,
114   ARG_HEIGHT,
115   ARG_VISIBLE,
116   ARG_SENSITIVE,
117   ARG_APP_PAINTABLE,
118   ARG_CAN_FOCUS,
119   ARG_HAS_FOCUS,
120   ARG_CAN_DEFAULT,
121   ARG_HAS_DEFAULT,
122   ARG_RECEIVES_DEFAULT,
123   ARG_COMPOSITE_CHILD,
124   ARG_STYLE,
125   ARG_EVENTS,
126   ARG_EXTENSION_EVENTS
127 };
128
129 typedef struct  _GtkStateData    GtkStateData;
130
131 struct _GtkStateData
132 {
133   GtkStateType  state;
134   guint         state_restoration : 1;
135   guint         parent_sensitive : 1;
136   guint         use_forall : 1;
137 };
138
139 static void gtk_widget_class_init                (GtkWidgetClass    *klass);
140 static void gtk_widget_init                      (GtkWidget         *widget);
141 static void gtk_widget_set_arg                   (GtkObject         *object,
142                                                   GtkArg            *arg,
143                                                   guint              arg_id);
144 static void gtk_widget_get_arg                   (GtkObject         *object,
145                                                   GtkArg            *arg,
146                                                   guint              arg_id);
147 static void gtk_widget_shutdown                  (GObject           *object);
148 static void gtk_widget_real_destroy              (GtkObject         *object);
149 static void gtk_widget_finalize                  (GObject           *object);
150 static void gtk_widget_real_show                 (GtkWidget         *widget);
151 static void gtk_widget_real_hide                 (GtkWidget         *widget);
152 static void gtk_widget_real_map                  (GtkWidget         *widget);
153 static void gtk_widget_real_unmap                (GtkWidget         *widget);
154 static void gtk_widget_real_realize              (GtkWidget         *widget);
155 static void gtk_widget_real_unrealize            (GtkWidget         *widget);
156 static void gtk_widget_real_draw                 (GtkWidget         *widget,
157                                                   GdkRectangle      *area);
158 static void gtk_widget_real_size_request         (GtkWidget         *widget,
159                                                   GtkRequisition    *requisition);
160 static void gtk_widget_real_size_allocate        (GtkWidget         *widget,
161                                                   GtkAllocation     *allocation);
162 static gint gtk_widget_real_key_press_event      (GtkWidget         *widget,
163                                                   GdkEventKey       *event);
164 static gint gtk_widget_real_key_release_event    (GtkWidget         *widget,
165                                                   GdkEventKey       *event);
166 static void gtk_widget_style_set                 (GtkWidget         *widget,
167                                                   GtkStyle          *previous_style);
168 static void gtk_widget_direction_changed         (GtkWidget         *widget,
169                                                   GtkTextDirection   previous_direction);
170 static void gtk_widget_real_grab_focus           (GtkWidget         *focus_widget);
171
172 static GdkColormap*  gtk_widget_peek_colormap      (void);
173 static GtkStyle*     gtk_widget_peek_style         (void);
174 static PangoContext *gtk_widget_peek_pango_context (GtkWidget *widget);
175
176 static void gtk_widget_reparent_container_child  (GtkWidget     *widget,
177                                                   gpointer       client_data);
178 static void gtk_widget_propagate_state           (GtkWidget     *widget,
179                                                   GtkStateData  *data);
180 static void gtk_widget_set_style_internal        (GtkWidget     *widget,
181                                                   GtkStyle      *style,
182                                                   gboolean       initial_emission);
183 static void gtk_widget_set_style_recurse         (GtkWidget     *widget,
184                                                   gpointer       client_data);
185
186 static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
187 static void              gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
188
189 static gpointer parent_class = NULL;
190 static guint widget_signals[LAST_SIGNAL] = { 0 };
191
192 static GMemChunk *aux_info_mem_chunk = NULL;
193
194 static GdkColormap *default_colormap = NULL;
195 static GtkStyle *gtk_default_style = NULL;
196
197 static GSList *colormap_stack = NULL;
198 static GSList *style_stack = NULL;
199 static guint   composite_child_stack = 0;
200
201 static const gchar *aux_info_key = "gtk-aux-info";
202 static guint        aux_info_key_id = 0;
203 static const gchar *event_key = "gtk-event-mask";
204 static guint        event_key_id = 0;
205 static const gchar *extension_event_key = "gtk-extension-event-mode";
206 static guint        extension_event_key_id = 0;
207 static const gchar *parent_window_key = "gtk-parent-window";
208 static guint        parent_window_key_id = 0;
209 static const gchar *saved_default_style_key = "gtk-saved-default-style";
210 static guint        saved_default_style_key_id = 0;
211 static const gchar *shape_info_key = "gtk-shape-info";
212 static const gchar *colormap_key = "gtk-colormap";
213 static const gchar *pango_context_key = "gtk-pango-context";
214 static guint        pango_context_key_id = 0;
215
216 static const gchar *rc_style_key = "gtk-rc-style";
217 static guint        rc_style_key_id = 0;
218
219 static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
220
221 /*****************************************
222  * gtk_widget_get_type:
223  *
224  *   arguments:
225  *
226  *   results:
227  *****************************************/
228
229 GtkType
230 gtk_widget_get_type (void)
231 {
232   static GtkType widget_type = 0;
233   
234   if (!widget_type)
235     {
236       static const GtkTypeInfo widget_info =
237       {
238         "GtkWidget",
239         sizeof (GtkWidget),
240         sizeof (GtkWidgetClass),
241         (GtkClassInitFunc) gtk_widget_class_init,
242         (GtkObjectInitFunc) gtk_widget_init,
243         /* reserved_1 */ NULL,
244         /* reserved_2 */ NULL,
245         (GtkClassInitFunc) NULL,
246       };
247       
248       widget_type = gtk_type_unique (GTK_TYPE_OBJECT, &widget_info);
249     }
250   
251   return widget_type;
252 }
253
254 /*****************************************
255  * gtk_widget_class_init:
256  *
257  *   arguments:
258  *
259  *   results:
260  *****************************************/
261 #include "stdio.h"
262 static void
263 gtk_widget_debug_msg (GtkWidget          *widget,
264                       const gchar        *string)
265 {
266   fprintf (stderr, "Gtk-DEBUG: %s\n", string);
267 }
268
269 static void
270 gtk_widget_class_init (GtkWidgetClass *klass)
271 {
272   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
273   GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
274   
275   parent_class = gtk_type_class (GTK_TYPE_OBJECT);
276
277   gobject_class->shutdown = gtk_widget_shutdown;
278   gobject_class->finalize = gtk_widget_finalize;
279
280   object_class->set_arg = gtk_widget_set_arg;
281   object_class->get_arg = gtk_widget_get_arg;
282   object_class->destroy = gtk_widget_real_destroy;
283   
284   klass->activate_signal = 0;
285   klass->set_scroll_adjustments_signal = 0;
286   klass->show = gtk_widget_real_show;
287   klass->show_all = gtk_widget_show;
288   klass->hide = gtk_widget_real_hide;
289   klass->hide_all = gtk_widget_hide;
290   klass->map = gtk_widget_real_map;
291   klass->unmap = gtk_widget_real_unmap;
292   klass->realize = gtk_widget_real_realize;
293   klass->unrealize = gtk_widget_real_unrealize;
294   klass->draw = gtk_widget_real_draw;
295   klass->draw_focus = NULL;
296   klass->size_request = gtk_widget_real_size_request;
297   klass->size_allocate = gtk_widget_real_size_allocate;
298   klass->state_changed = NULL;
299   klass->parent_set = NULL;
300   klass->style_set = gtk_widget_style_set;
301   klass->direction_changed = gtk_widget_direction_changed;
302   klass->add_accelerator = (void*) gtk_accel_group_handle_add;
303   klass->remove_accelerator = (void*) gtk_accel_group_handle_remove;
304   klass->grab_focus = gtk_widget_real_grab_focus;
305   klass->event = NULL;
306   klass->button_press_event = NULL;
307   klass->button_release_event = NULL;
308   klass->motion_notify_event = NULL;
309   klass->delete_event = NULL;
310   klass->destroy_event = NULL;
311   klass->expose_event = NULL;
312   klass->key_press_event = gtk_widget_real_key_press_event;
313   klass->key_release_event = gtk_widget_real_key_release_event;
314   klass->enter_notify_event = NULL;
315   klass->leave_notify_event = NULL;
316   klass->configure_event = NULL;
317   klass->focus_in_event = NULL;
318   klass->focus_out_event = NULL;
319   klass->map_event = NULL;
320   klass->unmap_event = NULL;
321   klass->property_notify_event = gtk_selection_property_notify;
322   klass->selection_clear_event = gtk_selection_clear;
323   klass->selection_request_event = gtk_selection_request;
324   klass->selection_notify_event = gtk_selection_notify;
325   klass->selection_received = NULL;
326   klass->proximity_in_event = NULL;
327   klass->proximity_out_event = NULL;
328   klass->drag_begin = NULL;
329   klass->drag_end = NULL;
330   klass->drag_data_delete = NULL;
331   klass->drag_leave = NULL;
332   klass->drag_motion = NULL;
333   klass->drag_drop = NULL;
334   klass->drag_data_received = NULL;
335
336   klass->no_expose_event = NULL;
337
338   klass->debug_msg = gtk_widget_debug_msg;
339   
340   gtk_object_add_arg_type ("GtkWidget::name", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NAME);
341   gtk_object_add_arg_type ("GtkWidget::parent", GTK_TYPE_CONTAINER, GTK_ARG_READWRITE, ARG_PARENT);
342   gtk_object_add_arg_type ("GtkWidget::x", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_X);
343   gtk_object_add_arg_type ("GtkWidget::y", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_Y);
344   gtk_object_add_arg_type ("GtkWidget::width", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_WIDTH);
345   gtk_object_add_arg_type ("GtkWidget::height", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_HEIGHT);
346   gtk_object_add_arg_type ("GtkWidget::visible", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_VISIBLE);
347   gtk_object_add_arg_type ("GtkWidget::sensitive", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SENSITIVE);
348   gtk_object_add_arg_type ("GtkWidget::app_paintable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_APP_PAINTABLE);
349   gtk_object_add_arg_type ("GtkWidget::can_focus", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_CAN_FOCUS);
350   gtk_object_add_arg_type ("GtkWidget::has_focus", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HAS_FOCUS);
351   gtk_object_add_arg_type ("GtkWidget::can_default", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_CAN_DEFAULT);
352   gtk_object_add_arg_type ("GtkWidget::has_default", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HAS_DEFAULT);
353   gtk_object_add_arg_type ("GtkWidget::receives_default", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_RECEIVES_DEFAULT);
354   gtk_object_add_arg_type ("GtkWidget::composite_child", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_COMPOSITE_CHILD);
355   gtk_object_add_arg_type ("GtkWidget::style", GTK_TYPE_STYLE, GTK_ARG_READWRITE, ARG_STYLE);
356   gtk_object_add_arg_type ("GtkWidget::events", GTK_TYPE_GDK_EVENT_MASK, GTK_ARG_READWRITE, ARG_EVENTS);
357   gtk_object_add_arg_type ("GtkWidget::extension_events", GTK_TYPE_GDK_EVENT_MASK, GTK_ARG_READWRITE, ARG_EXTENSION_EVENTS);
358   
359   widget_signals[SHOW] =
360     gtk_signal_new ("show",
361                     GTK_RUN_FIRST,
362                     GTK_CLASS_TYPE (object_class),
363                     GTK_SIGNAL_OFFSET (GtkWidgetClass, show),
364                     gtk_marshal_VOID__VOID,
365                     GTK_TYPE_NONE, 0);
366   widget_signals[HIDE] =
367     gtk_signal_new ("hide",
368                     GTK_RUN_FIRST,
369                     GTK_CLASS_TYPE (object_class),
370                     GTK_SIGNAL_OFFSET (GtkWidgetClass, hide),
371                     gtk_marshal_VOID__VOID,
372                     GTK_TYPE_NONE, 0);
373   widget_signals[MAP] =
374     gtk_signal_new ("map",
375                     GTK_RUN_FIRST,
376                     GTK_CLASS_TYPE (object_class),
377                     GTK_SIGNAL_OFFSET (GtkWidgetClass, map),
378                     gtk_marshal_VOID__VOID,
379                     GTK_TYPE_NONE, 0);
380   widget_signals[UNMAP] =
381     gtk_signal_new ("unmap",
382                     GTK_RUN_FIRST,
383                     GTK_CLASS_TYPE (object_class),
384                     GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap),
385                     gtk_marshal_VOID__VOID,
386                     GTK_TYPE_NONE, 0);
387   widget_signals[REALIZE] =
388     gtk_signal_new ("realize",
389                     GTK_RUN_FIRST,
390                     GTK_CLASS_TYPE (object_class),
391                     GTK_SIGNAL_OFFSET (GtkWidgetClass, realize),
392                     gtk_marshal_VOID__VOID,
393                     GTK_TYPE_NONE, 0);
394   widget_signals[UNREALIZE] =
395     gtk_signal_new ("unrealize",
396                     GTK_RUN_FIRST,
397                     GTK_CLASS_TYPE (object_class),
398                     GTK_SIGNAL_OFFSET (GtkWidgetClass, unrealize),
399                     gtk_marshal_VOID__VOID,
400                     GTK_TYPE_NONE, 0);
401   widget_signals[DRAW] =
402     gtk_signal_new ("draw",
403                     GTK_RUN_FIRST,
404                     GTK_CLASS_TYPE (object_class),
405                     GTK_SIGNAL_OFFSET (GtkWidgetClass, draw),
406                     gtk_marshal_VOID__POINTER,
407                     GTK_TYPE_NONE, 1,
408                     GTK_TYPE_POINTER);
409   widget_signals[DRAW_FOCUS] =
410     gtk_signal_new ("draw_focus",
411                     GTK_RUN_FIRST,
412                     GTK_CLASS_TYPE (object_class),
413                     GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_focus),
414                     gtk_marshal_VOID__VOID,
415                     GTK_TYPE_NONE, 0);
416   widget_signals[DRAW_DEFAULT] =
417     gtk_signal_new ("draw_default",
418                     GTK_RUN_FIRST,
419                     GTK_CLASS_TYPE (object_class),
420                     GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_default),
421                     gtk_marshal_VOID__VOID,
422                     GTK_TYPE_NONE, 0);
423   widget_signals[SIZE_REQUEST] =
424     gtk_signal_new ("size_request",
425                     GTK_RUN_FIRST,
426                     GTK_CLASS_TYPE (object_class),
427                     GTK_SIGNAL_OFFSET (GtkWidgetClass, size_request),
428                     gtk_marshal_VOID__POINTER,
429                     GTK_TYPE_NONE, 1,
430                     GTK_TYPE_POINTER);
431   widget_signals[SIZE_ALLOCATE] =
432     gtk_signal_new ("size_allocate",
433                     GTK_RUN_FIRST,
434                     GTK_CLASS_TYPE (object_class),
435                     GTK_SIGNAL_OFFSET (GtkWidgetClass, size_allocate),
436                     gtk_marshal_VOID__POINTER,
437                     GTK_TYPE_NONE, 1,
438                     GTK_TYPE_POINTER);
439   widget_signals[STATE_CHANGED] =
440     gtk_signal_new ("state_changed",
441                     GTK_RUN_FIRST,
442                     GTK_CLASS_TYPE (object_class),
443                     GTK_SIGNAL_OFFSET (GtkWidgetClass, state_changed),
444                     gtk_marshal_VOID__ENUM,
445                     GTK_TYPE_NONE, 1,
446                     GTK_TYPE_STATE_TYPE);
447   widget_signals[PARENT_SET] =
448     gtk_signal_new ("parent_set",
449                     GTK_RUN_FIRST,
450                     GTK_CLASS_TYPE (object_class),
451                     GTK_SIGNAL_OFFSET (GtkWidgetClass, parent_set),
452                     gtk_marshal_VOID__POINTER,
453                     GTK_TYPE_NONE, 1,
454                     GTK_TYPE_OBJECT);
455   widget_signals[STYLE_SET] =
456     gtk_signal_new ("style_set",
457                     GTK_RUN_FIRST,
458                     GTK_CLASS_TYPE (object_class),
459                     GTK_SIGNAL_OFFSET (GtkWidgetClass, style_set),
460                     gtk_marshal_VOID__POINTER,
461                     GTK_TYPE_NONE, 1,
462                     GTK_TYPE_STYLE);
463   widget_signals[DIRECTION_CHANGED] =
464     gtk_signal_new ("direction_changed",
465                     GTK_RUN_FIRST,
466                     GTK_CLASS_TYPE (object_class),
467                     GTK_SIGNAL_OFFSET (GtkWidgetClass, direction_changed),
468                     gtk_marshal_VOID__ENUM,
469                     GTK_TYPE_NONE, 1,
470                     GTK_TYPE_TEXT_DIRECTION);
471   widget_signals[ADD_ACCELERATOR] =
472     gtk_accel_group_create_add (GTK_CLASS_TYPE (object_class), GTK_RUN_LAST,
473                                 GTK_SIGNAL_OFFSET (GtkWidgetClass, add_accelerator));
474   widget_signals[REMOVE_ACCELERATOR] =
475     gtk_accel_group_create_remove (GTK_CLASS_TYPE (object_class), GTK_RUN_LAST,
476                                    GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator));
477   widget_signals[GRAB_FOCUS] =
478     gtk_signal_new ("grab_focus",
479                     GTK_RUN_LAST | GTK_RUN_ACTION,
480                     GTK_CLASS_TYPE (object_class),
481                     GTK_SIGNAL_OFFSET (GtkWidgetClass, grab_focus),
482                     gtk_marshal_VOID__VOID,
483                     GTK_TYPE_NONE, 0);
484   widget_signals[EVENT] =
485     gtk_signal_new ("event",
486                     GTK_RUN_LAST,
487                     GTK_CLASS_TYPE (object_class),
488                     GTK_SIGNAL_OFFSET (GtkWidgetClass, event),
489                     gtk_marshal_BOOLEAN__POINTER,
490                     GTK_TYPE_BOOL, 1,
491                     GTK_TYPE_GDK_EVENT);
492   widget_signals[BUTTON_PRESS_EVENT] =
493     gtk_signal_new ("button_press_event",
494                     GTK_RUN_LAST,
495                     GTK_CLASS_TYPE (object_class),
496                     GTK_SIGNAL_OFFSET (GtkWidgetClass, button_press_event),
497                     gtk_marshal_BOOLEAN__POINTER,
498                     GTK_TYPE_BOOL, 1,
499                     GTK_TYPE_GDK_EVENT);
500   widget_signals[BUTTON_RELEASE_EVENT] =
501     gtk_signal_new ("button_release_event",
502                     GTK_RUN_LAST,
503                     GTK_CLASS_TYPE (object_class),
504                     GTK_SIGNAL_OFFSET (GtkWidgetClass, button_release_event),
505                     gtk_marshal_BOOLEAN__POINTER,
506                     GTK_TYPE_BOOL, 1,
507                     GTK_TYPE_GDK_EVENT);
508   widget_signals[SCROLL_EVENT] =
509     gtk_signal_new ("scroll_event",
510                     GTK_RUN_LAST,
511                     GTK_CLASS_TYPE (object_class),
512                     GTK_SIGNAL_OFFSET (GtkWidgetClass, scroll_event),
513                     gtk_marshal_BOOLEAN__POINTER,
514                     GTK_TYPE_BOOL, 1,
515                     GTK_TYPE_GDK_EVENT);
516   widget_signals[MOTION_NOTIFY_EVENT] =
517     gtk_signal_new ("motion_notify_event",
518                     GTK_RUN_LAST,
519                     GTK_CLASS_TYPE (object_class),
520                     GTK_SIGNAL_OFFSET (GtkWidgetClass, motion_notify_event),
521                     gtk_marshal_BOOLEAN__POINTER,
522                     GTK_TYPE_BOOL, 1,
523                     GTK_TYPE_GDK_EVENT);
524   widget_signals[DELETE_EVENT] =
525     gtk_signal_new ("delete_event",
526                     GTK_RUN_LAST,
527                     GTK_CLASS_TYPE (object_class),
528                     GTK_SIGNAL_OFFSET (GtkWidgetClass, delete_event),
529                     gtk_marshal_BOOLEAN__POINTER,
530                     GTK_TYPE_BOOL, 1,
531                     GTK_TYPE_GDK_EVENT);
532   widget_signals[DESTROY_EVENT] =
533     gtk_signal_new ("destroy_event",
534                     GTK_RUN_LAST,
535                     GTK_CLASS_TYPE (object_class),
536                     GTK_SIGNAL_OFFSET (GtkWidgetClass, destroy_event),
537                     gtk_marshal_BOOLEAN__POINTER,
538                     GTK_TYPE_BOOL, 1,
539                     GTK_TYPE_GDK_EVENT);
540   widget_signals[EXPOSE_EVENT] =
541     gtk_signal_new ("expose_event",
542                     GTK_RUN_LAST,
543                     GTK_CLASS_TYPE (object_class),
544                     GTK_SIGNAL_OFFSET (GtkWidgetClass, expose_event),
545                     gtk_marshal_BOOLEAN__POINTER,
546                     GTK_TYPE_BOOL, 1,
547                     GTK_TYPE_GDK_EVENT);
548   widget_signals[KEY_PRESS_EVENT] =
549     gtk_signal_new ("key_press_event",
550                     GTK_RUN_LAST,
551                     GTK_CLASS_TYPE (object_class),
552                     GTK_SIGNAL_OFFSET (GtkWidgetClass, key_press_event),
553                     gtk_marshal_BOOLEAN__POINTER,
554                     GTK_TYPE_BOOL, 1,
555                     GTK_TYPE_GDK_EVENT);
556   widget_signals[KEY_RELEASE_EVENT] =
557     gtk_signal_new ("key_release_event",
558                     GTK_RUN_LAST,
559                     GTK_CLASS_TYPE (object_class),
560                     GTK_SIGNAL_OFFSET (GtkWidgetClass, key_release_event),
561                     gtk_marshal_BOOLEAN__POINTER,
562                     GTK_TYPE_BOOL, 1,
563                     GTK_TYPE_GDK_EVENT);
564   widget_signals[ENTER_NOTIFY_EVENT] =
565     gtk_signal_new ("enter_notify_event",
566                     GTK_RUN_LAST,
567                     GTK_CLASS_TYPE (object_class),
568                     GTK_SIGNAL_OFFSET (GtkWidgetClass, enter_notify_event),
569                     gtk_marshal_BOOLEAN__POINTER,
570                     GTK_TYPE_BOOL, 1,
571                     GTK_TYPE_GDK_EVENT);
572   widget_signals[LEAVE_NOTIFY_EVENT] =
573     gtk_signal_new ("leave_notify_event",
574                     GTK_RUN_LAST,
575                     GTK_CLASS_TYPE (object_class),
576                     GTK_SIGNAL_OFFSET (GtkWidgetClass, leave_notify_event),
577                     gtk_marshal_BOOLEAN__POINTER,
578                     GTK_TYPE_BOOL, 1,
579                     GTK_TYPE_GDK_EVENT);
580   widget_signals[CONFIGURE_EVENT] =
581     gtk_signal_new ("configure_event",
582                     GTK_RUN_LAST,
583                     GTK_CLASS_TYPE (object_class),
584                     GTK_SIGNAL_OFFSET (GtkWidgetClass, configure_event),
585                     gtk_marshal_BOOLEAN__POINTER,
586                     GTK_TYPE_BOOL, 1,
587                     GTK_TYPE_GDK_EVENT);
588   widget_signals[FOCUS_IN_EVENT] =
589     gtk_signal_new ("focus_in_event",
590                     GTK_RUN_LAST,
591                     GTK_CLASS_TYPE (object_class),
592                     GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_in_event),
593                     gtk_marshal_BOOLEAN__POINTER,
594                     GTK_TYPE_BOOL, 1,
595                     GTK_TYPE_GDK_EVENT);
596   widget_signals[FOCUS_OUT_EVENT] =
597     gtk_signal_new ("focus_out_event",
598                     GTK_RUN_LAST,
599                     GTK_CLASS_TYPE (object_class),
600                     GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_out_event),
601                     gtk_marshal_BOOLEAN__POINTER,
602                     GTK_TYPE_BOOL, 1,
603                     GTK_TYPE_GDK_EVENT);
604   widget_signals[MAP_EVENT] =
605     gtk_signal_new ("map_event",
606                     GTK_RUN_LAST,
607                     GTK_CLASS_TYPE (object_class),
608                     GTK_SIGNAL_OFFSET (GtkWidgetClass, map_event),
609                     gtk_marshal_BOOLEAN__POINTER,
610                     GTK_TYPE_BOOL, 1,
611                     GTK_TYPE_GDK_EVENT);
612   widget_signals[UNMAP_EVENT] =
613     gtk_signal_new ("unmap_event",
614                     GTK_RUN_LAST,
615                     GTK_CLASS_TYPE (object_class),
616                     GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap_event),
617                     gtk_marshal_BOOLEAN__POINTER,
618                     GTK_TYPE_BOOL, 1,
619                     GTK_TYPE_GDK_EVENT);
620   widget_signals[PROPERTY_NOTIFY_EVENT] =
621     gtk_signal_new ("property_notify_event",
622                     GTK_RUN_LAST,
623                     GTK_CLASS_TYPE (object_class),
624                     GTK_SIGNAL_OFFSET (GtkWidgetClass, property_notify_event),
625                     gtk_marshal_BOOLEAN__POINTER,
626                     GTK_TYPE_BOOL, 1,
627                     GTK_TYPE_GDK_EVENT);
628   widget_signals[SELECTION_CLEAR_EVENT] =
629     gtk_signal_new ("selection_clear_event",
630                     GTK_RUN_LAST,
631                     GTK_CLASS_TYPE (object_class),
632                     GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_clear_event),
633                     gtk_marshal_BOOLEAN__POINTER,
634                     GTK_TYPE_BOOL, 1,
635                     GTK_TYPE_GDK_EVENT);
636   widget_signals[SELECTION_REQUEST_EVENT] =
637     gtk_signal_new ("selection_request_event",
638                     GTK_RUN_LAST,
639                     GTK_CLASS_TYPE (object_class),
640                     GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_request_event),
641                     gtk_marshal_BOOLEAN__POINTER,
642                     GTK_TYPE_BOOL, 1,
643                     GTK_TYPE_GDK_EVENT);
644   widget_signals[SELECTION_NOTIFY_EVENT] =
645     gtk_signal_new ("selection_notify_event",
646                     GTK_RUN_LAST,
647                     GTK_CLASS_TYPE (object_class),
648                     GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_notify_event),
649                     gtk_marshal_BOOLEAN__POINTER,
650                     GTK_TYPE_BOOL, 1,
651                     GTK_TYPE_GDK_EVENT);
652   widget_signals[SELECTION_RECEIVED] =
653     gtk_signal_new ("selection_received",
654                     GTK_RUN_LAST,
655                     GTK_CLASS_TYPE (object_class),
656                     GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_received),
657                     gtk_marshal_VOID__POINTER_UINT,
658                     GTK_TYPE_NONE, 2,
659                     GTK_TYPE_SELECTION_DATA,
660                     GTK_TYPE_UINT);
661   widget_signals[SELECTION_GET] =
662     gtk_signal_new ("selection_get",
663                     GTK_RUN_LAST,
664                     GTK_CLASS_TYPE (object_class),
665                     GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_get),
666                     gtk_marshal_VOID__POINTER_UINT_UINT,
667                     GTK_TYPE_NONE, 3,
668                     GTK_TYPE_SELECTION_DATA,
669                     GTK_TYPE_UINT,
670                     GTK_TYPE_UINT);
671   widget_signals[PROXIMITY_IN_EVENT] =
672     gtk_signal_new ("proximity_in_event",
673                     GTK_RUN_LAST,
674                     GTK_CLASS_TYPE (object_class),
675                     GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_in_event),
676                     gtk_marshal_BOOLEAN__POINTER,
677                     GTK_TYPE_BOOL, 1,
678                     GTK_TYPE_GDK_EVENT);
679   widget_signals[PROXIMITY_OUT_EVENT] =
680     gtk_signal_new ("proximity_out_event",
681                     GTK_RUN_LAST,
682                     GTK_CLASS_TYPE (object_class),
683                     GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_out_event),
684                     gtk_marshal_BOOLEAN__POINTER,
685                     GTK_TYPE_BOOL, 1,
686                     GTK_TYPE_GDK_EVENT);
687   widget_signals[DRAG_LEAVE] =
688     gtk_signal_new ("drag_leave",
689                     GTK_RUN_LAST,
690                     GTK_CLASS_TYPE (object_class),
691                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_leave),
692                     gtk_marshal_VOID__POINTER_UINT,
693                     GTK_TYPE_NONE, 2,
694                     GDK_TYPE_DRAG_CONTEXT,
695                     GTK_TYPE_UINT);
696   widget_signals[DRAG_BEGIN] =
697     gtk_signal_new ("drag_begin",
698                     GTK_RUN_LAST,
699                     GTK_CLASS_TYPE (object_class),
700                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin),
701                     gtk_marshal_VOID__POINTER,
702                     GTK_TYPE_NONE, 1,
703                     GDK_TYPE_DRAG_CONTEXT);
704   widget_signals[DRAG_END] =
705     gtk_signal_new ("drag_end",
706                     GTK_RUN_LAST,
707                     GTK_CLASS_TYPE (object_class),
708                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end),
709                     gtk_marshal_VOID__POINTER,
710                     GTK_TYPE_NONE, 1,
711                     GDK_TYPE_DRAG_CONTEXT);
712   widget_signals[DRAG_DATA_DELETE] =
713     gtk_signal_new ("drag_data_delete",
714                     GTK_RUN_LAST,
715                     GTK_CLASS_TYPE (object_class),
716                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_delete),
717                     gtk_marshal_VOID__POINTER,
718                     GTK_TYPE_NONE, 1,
719                     GDK_TYPE_DRAG_CONTEXT);
720   widget_signals[DRAG_MOTION] =
721     gtk_signal_new ("drag_motion",
722                     GTK_RUN_LAST,
723                     GTK_CLASS_TYPE (object_class),
724                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_motion),
725                     gtk_marshal_BOOLEAN__POINTER_INT_INT_UINT,
726                     GTK_TYPE_BOOL, 4,
727                     GDK_TYPE_DRAG_CONTEXT,
728                     GTK_TYPE_INT,
729                     GTK_TYPE_INT,
730                     GTK_TYPE_UINT);
731   widget_signals[DRAG_DROP] =
732     gtk_signal_new ("drag_drop",
733                     GTK_RUN_LAST,
734                     GTK_CLASS_TYPE (object_class),
735                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_drop),
736                     gtk_marshal_BOOLEAN__POINTER_INT_INT_UINT,
737                     GTK_TYPE_BOOL, 4,
738                     GDK_TYPE_DRAG_CONTEXT,
739                     GTK_TYPE_INT,
740                     GTK_TYPE_INT,
741                     GTK_TYPE_UINT);
742   widget_signals[DRAG_DATA_GET] =
743     gtk_signal_new ("drag_data_get",
744                     GTK_RUN_LAST,
745                     GTK_CLASS_TYPE (object_class),
746                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_get),
747                     gtk_marshal_VOID__POINTER_POINTER_UINT_UINT,
748                     GTK_TYPE_NONE, 4,
749                     GDK_TYPE_DRAG_CONTEXT,
750                     GTK_TYPE_SELECTION_DATA,
751                     GTK_TYPE_UINT,
752                     GTK_TYPE_UINT);
753   widget_signals[DRAG_DATA_RECEIVED] =
754     gtk_signal_new ("drag_data_received",
755                     GTK_RUN_LAST,
756                     GTK_CLASS_TYPE (object_class),
757                     GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_received),
758                     gtk_marshal_VOID__POINTER_INT_INT_POINTER_UINT_UINT,
759                     GTK_TYPE_NONE, 6,
760                     GDK_TYPE_DRAG_CONTEXT,
761                     GTK_TYPE_INT,
762                     GTK_TYPE_INT,
763                     GTK_TYPE_SELECTION_DATA,
764                     GTK_TYPE_UINT,
765                     GTK_TYPE_UINT);
766   widget_signals[VISIBILITY_NOTIFY_EVENT] =
767     gtk_signal_new ("visibility_notify_event",
768                     GTK_RUN_LAST,
769                     GTK_CLASS_TYPE (object_class),
770                     GTK_SIGNAL_OFFSET (GtkWidgetClass, visibility_notify_event),
771                     gtk_marshal_BOOLEAN__POINTER,
772                     GTK_TYPE_BOOL, 1,
773                     GTK_TYPE_GDK_EVENT);
774   widget_signals[CLIENT_EVENT] =
775     gtk_signal_new ("client_event",
776                     GTK_RUN_LAST,
777                     GTK_CLASS_TYPE (object_class),
778                     GTK_SIGNAL_OFFSET (GtkWidgetClass, client_event),
779                     gtk_marshal_BOOLEAN__POINTER,
780                     GTK_TYPE_BOOL, 1,
781                     GTK_TYPE_GDK_EVENT);
782   widget_signals[NO_EXPOSE_EVENT] =
783     gtk_signal_new ("no_expose_event",
784                     GTK_RUN_LAST,
785                     GTK_CLASS_TYPE (object_class),
786                     GTK_SIGNAL_OFFSET (GtkWidgetClass, no_expose_event),
787                     gtk_marshal_BOOLEAN__POINTER,
788                     GTK_TYPE_BOOL, 1,
789                     GTK_TYPE_GDK_EVENT);
790   widget_signals[DEBUG_MSG] =
791     gtk_signal_new ("debug_msg",
792                     GTK_RUN_LAST | GTK_RUN_ACTION,
793                     GTK_CLASS_TYPE (object_class),
794                     GTK_SIGNAL_OFFSET (GtkWidgetClass, debug_msg),
795                     gtk_marshal_VOID__POINTER,
796                     GTK_TYPE_NONE, 1,
797                     GTK_TYPE_STRING);
798
799   gtk_object_class_add_signals (object_class, widget_signals, LAST_SIGNAL);
800 }
801
802 static void
803 gtk_widget_set_arg (GtkObject   *object,
804                     GtkArg      *arg,
805                     guint        arg_id)
806 {
807   GtkWidget *widget;
808
809   widget = GTK_WIDGET (object);
810
811   switch (arg_id)
812     {
813       guint32 saved_flags;
814       
815     case ARG_NAME:
816       gtk_widget_set_name (widget, GTK_VALUE_STRING (*arg));
817       break;
818     case ARG_PARENT:
819       gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT (*arg)), widget);
820       break;
821     case ARG_X:
822       gtk_widget_set_uposition (widget, GTK_VALUE_INT (*arg), -2);
823       break;
824     case ARG_Y:
825       gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT (*arg));
826       break;
827     case ARG_WIDTH:
828       gtk_widget_set_usize (widget, GTK_VALUE_INT (*arg), -2);
829       break;
830     case ARG_HEIGHT:
831       gtk_widget_set_usize (widget, -2, GTK_VALUE_INT (*arg));
832       break;
833     case ARG_VISIBLE:
834       if (GTK_VALUE_BOOL(*arg))
835         gtk_widget_show (widget);
836       else
837         gtk_widget_hide (widget);
838       break;
839     case ARG_SENSITIVE:
840       gtk_widget_set_sensitive (widget, GTK_VALUE_BOOL (*arg));
841       break;
842     case ARG_APP_PAINTABLE:
843       gtk_widget_set_app_paintable (widget, GTK_VALUE_BOOL (*arg));
844       break;
845     case ARG_CAN_FOCUS:
846       saved_flags = GTK_WIDGET_FLAGS (widget);
847       if (GTK_VALUE_BOOL (*arg))
848         GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
849       else
850         GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
851       if (saved_flags != GTK_WIDGET_FLAGS (widget))
852         gtk_widget_queue_resize (widget);
853       break;
854     case ARG_HAS_FOCUS:
855       if (GTK_VALUE_BOOL (*arg))
856         gtk_widget_grab_focus (widget);
857       break;
858     case ARG_CAN_DEFAULT:
859       saved_flags = GTK_WIDGET_FLAGS (widget);
860       if (GTK_VALUE_BOOL (*arg))
861         GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
862       else
863         GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
864       if (saved_flags != GTK_WIDGET_FLAGS (widget))
865         gtk_widget_queue_resize (widget);
866       break;
867     case ARG_HAS_DEFAULT:
868       if (GTK_VALUE_BOOL (*arg))
869         gtk_widget_grab_default (widget);
870       break;
871     case ARG_RECEIVES_DEFAULT:
872       if (GTK_VALUE_BOOL (*arg))
873         GTK_WIDGET_SET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
874       else
875         GTK_WIDGET_UNSET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
876       break;
877     case ARG_COMPOSITE_CHILD:
878       if (GTK_VALUE_BOOL(*arg))
879         GTK_WIDGET_SET_FLAGS (widget, GTK_COMPOSITE_CHILD);
880       else
881         GTK_WIDGET_UNSET_FLAGS (widget, GTK_COMPOSITE_CHILD);
882       break;
883     case ARG_STYLE:
884       gtk_widget_set_style (widget, (GtkStyle*) GTK_VALUE_BOXED (*arg));
885       break;
886     case ARG_EVENTS:
887       if (!GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget))
888         gtk_widget_set_events (widget, GTK_VALUE_FLAGS (*arg));
889       break;
890     case ARG_EXTENSION_EVENTS:
891       gtk_widget_set_extension_events (widget, GTK_VALUE_FLAGS (*arg));
892       break;
893     default:
894       break;
895     }
896 }
897
898 /*****************************************
899  * gtk_widget_get_arg:
900  *
901  *   arguments:
902  *
903  *   results:
904  *****************************************/
905
906 static void
907 gtk_widget_get_arg (GtkObject   *object,
908                     GtkArg      *arg,
909                     guint        arg_id)
910 {
911   GtkWidget *widget;
912
913   widget = GTK_WIDGET (object);
914   
915   switch (arg_id)
916     {
917       GtkWidgetAuxInfo *aux_info;
918       gint *eventp;
919       GdkExtensionMode *modep;
920
921     case ARG_NAME:
922       if (widget->name)
923         GTK_VALUE_STRING (*arg) = g_strdup (widget->name);
924       else
925         GTK_VALUE_STRING (*arg) = g_strdup ("");
926       break;
927     case ARG_PARENT:
928       GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
929       break;
930     case ARG_X:
931       aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
932       if (!aux_info)
933         GTK_VALUE_INT (*arg) = -1;
934       else
935         GTK_VALUE_INT (*arg) = aux_info->x;
936       break;
937     case ARG_Y:
938       aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
939       if (!aux_info)
940         GTK_VALUE_INT (*arg) = -1;
941       else
942         GTK_VALUE_INT (*arg) = aux_info->y;
943       break;
944     case ARG_WIDTH:
945       aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
946       if (!aux_info)
947         GTK_VALUE_INT (*arg) = -1;
948       else
949         GTK_VALUE_INT (*arg) = aux_info->width;
950       break;
951     case ARG_HEIGHT:
952       aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
953       if (!aux_info)
954         GTK_VALUE_INT (*arg) = -1;
955       else
956         GTK_VALUE_INT (*arg) = aux_info->height;
957       break;
958     case ARG_VISIBLE:
959       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_VISIBLE (widget) != FALSE);
960       break;
961     case ARG_SENSITIVE:
962       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_SENSITIVE (widget) != FALSE);
963       break;
964     case ARG_APP_PAINTABLE:
965       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_APP_PAINTABLE (widget) != FALSE);
966       break;
967     case ARG_CAN_FOCUS:
968       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_FOCUS (widget) != FALSE);
969       break;
970     case ARG_HAS_FOCUS:
971       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_FOCUS (widget) != FALSE);
972       break;
973     case ARG_CAN_DEFAULT:
974       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE);
975       break;
976     case ARG_HAS_DEFAULT:
977       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_DEFAULT (widget) != FALSE);
978       break;
979     case ARG_RECEIVES_DEFAULT:
980       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_RECEIVES_DEFAULT (widget) != FALSE);
981       break;
982     case ARG_COMPOSITE_CHILD:
983       GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_COMPOSITE_CHILD (widget) != FALSE);
984       break;
985     case ARG_STYLE:
986       GTK_VALUE_BOXED (*arg) = (gpointer) gtk_widget_get_style (widget);
987       break;
988     case ARG_EVENTS:
989       eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
990       if (!eventp)
991         GTK_VALUE_FLAGS (*arg) = 0;
992       else
993         GTK_VALUE_FLAGS (*arg) = *eventp;
994       break;
995     case ARG_EXTENSION_EVENTS:
996       modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
997       if (!modep)
998         GTK_VALUE_FLAGS (*arg) = 0;
999       else
1000         GTK_VALUE_FLAGS (*arg) = *modep;
1001       break;
1002     default:
1003       arg->type = GTK_TYPE_INVALID;
1004       break;
1005     }
1006 }
1007
1008 /*****************************************
1009  * gtk_widget_init:
1010  *
1011  *   arguments:
1012  *
1013  *   results:
1014  *****************************************/
1015
1016 static void
1017 gtk_widget_init (GtkWidget *widget)
1018 {
1019   GdkColormap *colormap;
1020   
1021   GTK_PRIVATE_FLAGS (widget) = 0;
1022   widget->state = GTK_STATE_NORMAL;
1023   widget->saved_state = GTK_STATE_NORMAL;
1024   widget->name = NULL;
1025   widget->requisition.width = 0;
1026   widget->requisition.height = 0;
1027   widget->allocation.x = -1;
1028   widget->allocation.y = -1;
1029   widget->allocation.width = 1;
1030   widget->allocation.height = 1;
1031   widget->window = NULL;
1032   widget->parent = NULL;
1033
1034   GTK_WIDGET_SET_FLAGS (widget,
1035                         GTK_SENSITIVE |
1036                         GTK_PARENT_SENSITIVE |
1037                         (composite_child_stack ? GTK_COMPOSITE_CHILD : 0) |
1038                         GTK_DOUBLE_BUFFERED);
1039
1040   widget->style = gtk_widget_peek_style ();
1041   gtk_style_ref (widget->style);
1042   
1043   colormap = gtk_widget_peek_colormap ();
1044   
1045   if (colormap != gtk_widget_get_default_colormap ())
1046     gtk_widget_set_colormap (widget, colormap);
1047 }
1048
1049 /*****************************************
1050  * gtk_widget_new:
1051  *
1052  *   arguments:
1053  *
1054  *   results:
1055  *****************************************/
1056
1057 GtkWidget*
1058 gtk_widget_new (GtkType      widget_type,
1059                 const gchar *first_arg_name,
1060                 ...)
1061 {
1062   GtkObject *object;
1063   va_list var_args;
1064   GSList *arg_list = NULL;
1065   GSList *info_list = NULL;
1066   gchar *error;
1067   
1068   g_return_val_if_fail (gtk_type_is_a (widget_type, GTK_TYPE_WIDGET), NULL);
1069   
1070   object = gtk_type_new (widget_type);
1071   
1072   va_start (var_args, first_arg_name);
1073   error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1074                                    &arg_list,
1075                                    &info_list,
1076                                    first_arg_name,
1077                                    var_args);
1078   va_end (var_args);
1079   
1080   if (error)
1081     {
1082       g_warning ("gtk_widget_new(): %s", error);
1083       g_free (error);
1084     }
1085   else
1086     {
1087       GSList *slist_arg;
1088       GSList *slist_info;
1089       
1090       slist_arg = arg_list;
1091       slist_info = info_list;
1092       while (slist_arg)
1093         {
1094           gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1095           slist_arg = slist_arg->next;
1096           slist_info = slist_info->next;
1097         }
1098       gtk_args_collect_cleanup (arg_list, info_list);
1099     }
1100   
1101   if (!GTK_OBJECT_CONSTRUCTED (object))
1102     gtk_object_default_construct (object);
1103
1104   return GTK_WIDGET (object);
1105 }
1106
1107 /*****************************************
1108  * gtk_widget_newv:
1109  *
1110  *   arguments:
1111  *
1112  *   results:
1113  *****************************************/
1114
1115 GtkWidget*
1116 gtk_widget_newv (GtkType type,
1117                  guint   nargs,
1118                  GtkArg *args)
1119 {
1120   g_return_val_if_fail (gtk_type_is_a (type, GTK_TYPE_WIDGET), NULL);
1121   
1122   return GTK_WIDGET (gtk_object_newv (type, nargs, args));
1123 }
1124
1125 /*****************************************
1126  * gtk_widget_get:
1127  *
1128  *   arguments:
1129  *
1130  *   results:
1131  *****************************************/
1132
1133 void
1134 gtk_widget_get (GtkWidget       *widget,
1135                 GtkArg          *arg)
1136 {
1137   g_return_if_fail (widget != NULL);
1138   g_return_if_fail (GTK_IS_WIDGET (widget));
1139   g_return_if_fail (arg != NULL);
1140   
1141   gtk_object_getv (GTK_OBJECT (widget), 1, arg);
1142 }
1143
1144 /*****************************************
1145  * gtk_widget_getv:
1146  *
1147  *   arguments:
1148  *
1149  *   results:
1150  *****************************************/
1151
1152 void
1153 gtk_widget_getv (GtkWidget      *widget,
1154                  guint           nargs,
1155                  GtkArg         *args)
1156 {
1157   g_return_if_fail (widget != NULL);
1158   g_return_if_fail (GTK_IS_WIDGET (widget));
1159
1160   gtk_object_getv (GTK_OBJECT (widget), nargs, args);
1161 }
1162
1163 /*****************************************
1164  * gtk_widget_set:
1165  *
1166  *   arguments:
1167  *
1168  *   results:
1169  *****************************************/
1170
1171 void
1172 gtk_widget_set (GtkWidget   *widget,
1173                 const gchar *first_arg_name,
1174                 ...)
1175 {
1176   GtkObject *object;
1177   va_list var_args;
1178   GSList *arg_list = NULL;
1179   GSList *info_list = NULL;
1180   gchar *error;
1181
1182   g_return_if_fail (widget != NULL);
1183   g_return_if_fail (GTK_IS_WIDGET (widget));
1184
1185   object = GTK_OBJECT (widget);
1186
1187   va_start (var_args, first_arg_name);
1188   error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1189                                    &arg_list,
1190                                    &info_list,
1191                                    first_arg_name,
1192                                    var_args);
1193   va_end (var_args);
1194
1195   if (error)
1196     {
1197       g_warning ("gtk_widget_set(): %s", error);
1198       g_free (error);
1199     }
1200   else
1201     {
1202       GSList *slist_arg;
1203       GSList *slist_info;
1204
1205       slist_arg = arg_list;
1206       slist_info = info_list;
1207       while (slist_arg)
1208         {
1209           gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1210           slist_arg = slist_arg->next;
1211           slist_info = slist_info->next;
1212         }
1213       gtk_args_collect_cleanup (arg_list, info_list);
1214     }
1215 }
1216
1217 /*****************************************
1218  * gtk_widget_setv:
1219  *
1220  *   arguments:
1221  *
1222  *   results:
1223  *****************************************/
1224
1225 void
1226 gtk_widget_setv (GtkWidget *widget,
1227                  guint      nargs,
1228                  GtkArg    *args)
1229 {
1230   g_return_if_fail (widget != NULL);
1231   g_return_if_fail (GTK_IS_WIDGET (widget));
1232
1233   gtk_object_setv (GTK_OBJECT (widget), nargs, args);
1234 }
1235
1236 static inline void         
1237 gtk_widget_queue_clear_child (GtkWidget *widget)
1238 {
1239   GtkWidget *parent;
1240
1241   parent = widget->parent;
1242   if (parent && GTK_WIDGET_DRAWABLE (parent))
1243     gtk_widget_queue_clear_area (parent,
1244                                  widget->allocation.x,
1245                                  widget->allocation.y,
1246                                  widget->allocation.width,
1247                                  widget->allocation.height);
1248 }
1249
1250 void
1251 gtk_widget_unparent (GtkWidget *widget)
1252 {
1253   GtkWidget *toplevel;
1254   GtkWidget *old_parent;
1255   
1256   g_return_if_fail (widget != NULL);
1257   g_return_if_fail (GTK_IS_WIDGET (widget));
1258   if (widget->parent == NULL)
1259     return;
1260   
1261   /* keep this function in sync with gtk_menu_detach()
1262    */
1263
1264   /* unset focused and default children properly, this code
1265    * should eventually move into some gtk_window_unparent_branch() or
1266    * similar function.
1267    */
1268   
1269   toplevel = gtk_widget_get_toplevel (widget);
1270   if (GTK_CONTAINER (widget->parent)->focus_child == widget)
1271     {
1272       gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
1273
1274       if (GTK_IS_WINDOW (toplevel))
1275         {
1276           GtkWidget *child;
1277       
1278           child = GTK_WINDOW (toplevel)->focus_widget;
1279           
1280           while (child && child != widget)
1281             child = child->parent;
1282           
1283           if (child == widget)
1284             gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
1285         }
1286     }
1287   if (GTK_IS_WINDOW (toplevel))
1288     {
1289       GtkWidget *child;
1290       
1291       child = GTK_WINDOW (toplevel)->default_widget;
1292       
1293       while (child && child != widget)
1294         child = child->parent;
1295       
1296       if (child == widget)
1297         gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
1298     }
1299
1300   if (GTK_IS_RESIZE_CONTAINER (widget))
1301     gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
1302   
1303   /* Remove the widget and all its children from any ->resize_widgets list
1304    * of all the parents in our branch. This code should move into gtkcontainer.c
1305    * somwhen, since we mess around with ->resize_widgets, which is
1306    * actually not of our business.
1307    *
1308    * Two ways to make this prettier:
1309    *   Write a g_slist_conditional_remove (GSList, gboolean (*)(gpointer))
1310    *   Change resize_widgets to a GList
1311    */
1312   toplevel = widget->parent;
1313   while (toplevel)
1314     {
1315       GSList *slist;
1316       GSList *prev;
1317
1318       if (!GTK_CONTAINER (toplevel)->resize_widgets)
1319         {
1320           toplevel = toplevel->parent;
1321           continue;
1322         }
1323
1324       prev = NULL;
1325       slist = GTK_CONTAINER (toplevel)->resize_widgets;
1326       while (slist)
1327         {
1328           GtkWidget *child;
1329           GtkWidget *parent;
1330           GSList *last;
1331
1332           last = slist;
1333           slist = last->next;
1334           child = last->data;
1335           
1336           parent = child;
1337           while (parent && (parent != widget))
1338             parent = parent->parent;
1339           
1340           if (parent == widget)
1341             {
1342               GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
1343               
1344               if (prev)
1345                 prev->next = slist;
1346               else
1347                 GTK_CONTAINER (toplevel)->resize_widgets = slist;
1348               
1349               g_slist_free_1 (last);
1350             }
1351           else
1352             prev = last;
1353         }
1354
1355       toplevel = toplevel->parent;
1356     }
1357
1358   gtk_widget_queue_clear_child (widget);
1359
1360   /* Reset the width and height here, to force reallocation if we
1361    * get added back to a new parent. This won't work if our new
1362    * allocation is smaller than 1x1 and we actually want a size of 1x1...
1363    * (would 0x0 be OK here?)
1364    */
1365   widget->allocation.width = 1;
1366   widget->allocation.height = 1;
1367   
1368   if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_IN_REPARENT (widget))
1369     gtk_widget_unrealize (widget);
1370
1371   old_parent = widget->parent;
1372   widget->parent = NULL;
1373   gtk_widget_set_parent_window (widget, NULL);
1374   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], old_parent);
1375   
1376   gtk_widget_unref (widget);
1377 }
1378
1379 /*****************************************
1380  * gtk_widget_destroy:
1381  *
1382  *   arguments:
1383  *
1384  *   results:
1385  *****************************************/
1386
1387 void
1388 gtk_widget_destroy (GtkWidget *widget)
1389 {
1390   g_return_if_fail (widget != NULL);
1391   g_return_if_fail (GTK_IS_WIDGET (widget));
1392   g_return_if_fail (GTK_OBJECT_CONSTRUCTED (widget));
1393
1394   gtk_object_destroy ((GtkObject*) widget);
1395 }
1396
1397 /*****************************************
1398  * gtk_widget_destroyed:
1399  *   Utility function: sets widget_pointer 
1400  *   to NULL when widget is destroyed.
1401  *
1402  *   arguments:
1403  *
1404  *   results:
1405  *****************************************/
1406
1407 void
1408 gtk_widget_destroyed (GtkWidget      *widget,
1409                       GtkWidget      **widget_pointer)
1410 {
1411   /* Don't make any assumptions about the
1412    *  value of widget!
1413    *  Even check widget_pointer.
1414    */
1415   if (widget_pointer)
1416     *widget_pointer = NULL;
1417 }
1418
1419 /*****************************************
1420  * gtk_widget_show:
1421  *
1422  *   arguments:
1423  *
1424  *   results:
1425  *****************************************/
1426
1427 void
1428 gtk_widget_show (GtkWidget *widget)
1429 {
1430   g_return_if_fail (widget != NULL);
1431   g_return_if_fail (GTK_IS_WIDGET (widget));
1432   
1433   if (!GTK_WIDGET_VISIBLE (widget))
1434     {
1435       if (!GTK_WIDGET_TOPLEVEL (widget))
1436         gtk_widget_queue_resize (widget);
1437       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SHOW]);
1438     }
1439 }
1440
1441 static void
1442 gtk_widget_real_show (GtkWidget *widget)
1443 {
1444   g_return_if_fail (widget != NULL);
1445   g_return_if_fail (GTK_IS_WIDGET (widget));
1446   
1447   if (!GTK_WIDGET_VISIBLE (widget))
1448     {
1449       GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
1450
1451       if (widget->parent &&
1452           GTK_WIDGET_MAPPED (widget->parent) &&
1453           !GTK_WIDGET_MAPPED (widget))
1454         gtk_widget_map (widget);
1455     }
1456 }
1457
1458 /*************************************************************
1459  * gtk_widget_show_now:
1460  *   Show a widget, and if it is an unmapped toplevel widget
1461  *   wait for the map_event before returning
1462  *
1463  *   Warning: This routine will call the main loop recursively.
1464  *       
1465  *   arguments:
1466  *     
1467  *   results:
1468  *************************************************************/
1469
1470 static void
1471 gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
1472 {
1473   *flag = TRUE;
1474   gtk_signal_disconnect_by_data (GTK_OBJECT (widget), flag);
1475 }
1476
1477 void
1478 gtk_widget_show_now (GtkWidget *widget)
1479 {
1480   gint flag = FALSE;
1481   
1482   g_return_if_fail (widget != NULL);
1483   g_return_if_fail (GTK_IS_WIDGET (widget));
1484
1485   /* make sure we will get event */
1486   if (!GTK_WIDGET_MAPPED (widget) &&
1487       GTK_WIDGET_TOPLEVEL (widget))
1488     {
1489       gtk_widget_show (widget);
1490
1491       gtk_signal_connect (GTK_OBJECT (widget), "map_event",
1492                           GTK_SIGNAL_FUNC (gtk_widget_show_map_callback), 
1493                           &flag);
1494
1495       while (!flag)
1496         gtk_main_iteration();
1497     }
1498   else
1499     gtk_widget_show (widget);
1500 }
1501
1502 /*****************************************
1503  * gtk_widget_hide:
1504  *
1505  *   arguments:
1506  *
1507  *   results:
1508  *****************************************/
1509
1510 void
1511 gtk_widget_hide (GtkWidget *widget)
1512 {
1513   g_return_if_fail (widget != NULL);
1514   g_return_if_fail (GTK_IS_WIDGET (widget));
1515   
1516   if (GTK_WIDGET_VISIBLE (widget))
1517     {
1518       gtk_widget_ref (widget);
1519       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[HIDE]);
1520       if (!GTK_WIDGET_TOPLEVEL (widget) && !GTK_OBJECT_DESTROYED (widget))
1521         gtk_widget_queue_resize (widget);
1522       gtk_widget_unref (widget);
1523     }
1524 }
1525
1526 static void
1527 gtk_widget_real_hide (GtkWidget *widget)
1528 {
1529   g_return_if_fail (widget != NULL);
1530   g_return_if_fail (GTK_IS_WIDGET (widget));
1531   
1532   if (GTK_WIDGET_VISIBLE (widget))
1533     {
1534       GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
1535       
1536       if (GTK_WIDGET_MAPPED (widget))
1537         gtk_widget_unmap (widget);
1538     }
1539 }
1540
1541 gint
1542 gtk_widget_hide_on_delete (GtkWidget      *widget)
1543 {
1544   g_return_val_if_fail (widget != NULL, FALSE);
1545   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1546   
1547   gtk_widget_hide (widget);
1548   
1549   return TRUE;
1550 }
1551
1552 void
1553 gtk_widget_show_all (GtkWidget *widget)
1554 {
1555   GtkWidgetClass *class;
1556
1557   g_return_if_fail (widget != NULL);
1558   g_return_if_fail (GTK_IS_WIDGET (widget));
1559
1560   class = GTK_WIDGET_GET_CLASS (widget);
1561
1562   if (class->show_all)
1563     class->show_all (widget);
1564 }
1565
1566 void
1567 gtk_widget_hide_all (GtkWidget *widget)
1568 {
1569   GtkWidgetClass *class;
1570
1571   g_return_if_fail (widget != NULL);
1572   g_return_if_fail (GTK_IS_WIDGET (widget));
1573
1574   class = GTK_WIDGET_GET_CLASS (widget);
1575
1576   if (class->hide_all)
1577     class->hide_all (widget);
1578 }
1579
1580 /*****************************************
1581  * gtk_widget_map:
1582  *
1583  *   arguments:
1584  *
1585  *   results:
1586  *****************************************/
1587
1588 void
1589 gtk_widget_map (GtkWidget *widget)
1590 {
1591   g_return_if_fail (GTK_IS_WIDGET (widget));
1592   g_return_if_fail (GTK_WIDGET_VISIBLE (widget) == TRUE);
1593   
1594   if (!GTK_WIDGET_MAPPED (widget))
1595     {
1596       if (!GTK_WIDGET_REALIZED (widget))
1597         gtk_widget_realize (widget);
1598
1599       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
1600
1601       if (GTK_WIDGET_NO_WINDOW (widget))
1602         gtk_widget_queue_draw (widget);
1603     }
1604 }
1605
1606 /*****************************************
1607  * gtk_widget_unmap:
1608  *
1609  *   arguments:
1610  *
1611  *   results:
1612  *****************************************/
1613
1614 void
1615 gtk_widget_unmap (GtkWidget *widget)
1616 {
1617   g_return_if_fail (widget != NULL);
1618   g_return_if_fail (GTK_IS_WIDGET (widget));
1619   
1620   if (GTK_WIDGET_MAPPED (widget))
1621     {
1622       if (GTK_WIDGET_NO_WINDOW (widget))
1623         gtk_widget_queue_clear_child (widget);
1624       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
1625     }
1626 }
1627
1628 /*****************************************
1629  * gtk_widget_realize:
1630  *
1631  *   arguments:
1632  *
1633  *   results:
1634  *****************************************/
1635
1636 void
1637 gtk_widget_realize (GtkWidget *widget)
1638 {
1639   gint events;
1640   GdkExtensionMode mode;
1641   GtkWidgetShapeInfo *shape_info;
1642   
1643   g_return_if_fail (widget != NULL);
1644   g_return_if_fail (GTK_IS_WIDGET (widget));
1645   
1646   if (!GTK_WIDGET_REALIZED (widget))
1647     {
1648       /*
1649         if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
1650           g_message ("gtk_widget_realize(%s)", gtk_type_name (GTK_WIDGET_TYPE (widget)));
1651       */
1652       
1653       if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
1654         gtk_widget_realize (widget->parent);
1655
1656       gtk_widget_ensure_style (widget);
1657       
1658       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);
1659       
1660       if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1661         {
1662           shape_info = gtk_object_get_data (GTK_OBJECT (widget),
1663                                             shape_info_key);
1664           gdk_window_shape_combine_mask (widget->window,
1665                                          shape_info->shape_mask,
1666                                          shape_info->offset_x,
1667                                          shape_info->offset_y);
1668         }
1669       
1670       if (!GTK_WIDGET_NO_WINDOW (widget))
1671         {
1672           mode = gtk_widget_get_extension_events (widget);
1673           if (mode != GDK_EXTENSION_EVENTS_NONE)
1674             {
1675               events = gtk_widget_get_events (widget);
1676               gdk_input_set_extension_events (widget->window, events, mode);
1677             }
1678         }
1679       
1680     }
1681 }
1682
1683 /*****************************************
1684  * gtk_widget_unrealize:
1685  *
1686  *   arguments:
1687  *
1688  *   results:
1689  *****************************************/
1690
1691 void
1692 gtk_widget_unrealize (GtkWidget *widget)
1693 {
1694   g_return_if_fail (widget != NULL);
1695   g_return_if_fail (GTK_IS_WIDGET (widget));
1696
1697   if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1698     gtk_widget_shape_combine_mask (widget, NULL, -1, -1);
1699
1700   if (GTK_WIDGET_REALIZED (widget))
1701     {
1702       gtk_widget_ref (widget);
1703       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);
1704       GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
1705       gtk_widget_unref (widget);
1706     }
1707 }
1708
1709 /*****************************************
1710  * Draw queueing.
1711  *****************************************/
1712
1713 void       
1714 gtk_widget_queue_draw_area (GtkWidget *widget,
1715                             gint       x,
1716                             gint       y,
1717                             gint       width,
1718                             gint       height)
1719 {
1720   g_return_if_fail (widget != NULL);
1721   g_return_if_fail (GTK_IS_WIDGET (widget));
1722
1723   gtk_widget_queue_clear_area (widget, x, y, width, height);
1724 }
1725
1726 void       
1727 gtk_widget_queue_draw (GtkWidget *widget)
1728 {
1729   g_return_if_fail (widget != NULL);
1730   g_return_if_fail (GTK_IS_WIDGET (widget));
1731
1732   gtk_widget_queue_clear (widget);
1733 }
1734
1735 /* Invalidates the given area (allocation-relative-coordinates)
1736  * in all of the widget's windows
1737  */
1738 void       
1739 gtk_widget_queue_clear_area (GtkWidget *widget,
1740                              gint       x,
1741                              gint       y,
1742                              gint       width,
1743                              gint       height)
1744 {
1745   GdkRectangle invalid_rect;
1746   
1747   g_return_if_fail (widget != NULL);
1748   g_return_if_fail (GTK_IS_WIDGET (widget));
1749
1750   if (!(widget->window && gdk_window_is_viewable (widget->window)))
1751     return;
1752
1753   /* Find the correct widget */
1754
1755   if (!GTK_WIDGET_NO_WINDOW (widget))
1756     {
1757       if (widget->parent)
1758         {
1759           /* Translate widget relative to window-relative */
1760
1761           gint wx, wy, wwidth, wheight;
1762           
1763           gdk_window_get_position (widget->window, &wx, &wy);
1764           x -= wx - widget->allocation.x;
1765           y -= wy - widget->allocation.y;
1766           
1767           gdk_window_get_size (widget->window, &wwidth, &wheight);
1768
1769           if (x + width <= 0 || y + height <= 0 ||
1770               x >= wwidth || y >= wheight)
1771             return;
1772           
1773           if (x < 0)
1774             {
1775               width += x;  x = 0;
1776             }
1777           if (y < 0)
1778             {
1779               height += y; y = 0;
1780             }
1781           if (x + width > wwidth)
1782             width = wwidth - x;
1783           if (y + height > wheight)
1784             height = wheight - y;
1785         }
1786     }
1787
1788   invalid_rect.x = x;
1789   invalid_rect.y = y;
1790   invalid_rect.width = width;
1791   invalid_rect.height = height;
1792   
1793   gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
1794 }
1795
1796 void       
1797 gtk_widget_queue_clear (GtkWidget *widget)
1798 {
1799   g_return_if_fail (widget != NULL);
1800   g_return_if_fail (GTK_IS_WIDGET (widget));
1801
1802   if (widget->allocation.width || widget->allocation.height)
1803     {
1804       if (GTK_WIDGET_NO_WINDOW (widget))
1805         gtk_widget_queue_clear_area (widget, widget->allocation.x,
1806                                      widget->allocation.y,
1807                                      widget->allocation.width, 
1808                                      widget->allocation.height);
1809       else
1810         gtk_widget_queue_clear_area (widget, 0, 0, 
1811                                      widget->allocation.width, 
1812                                      widget->allocation.height);
1813     }
1814 }
1815
1816 void
1817 gtk_widget_queue_resize (GtkWidget *widget)
1818 {
1819   g_return_if_fail (widget != NULL);
1820   g_return_if_fail (GTK_IS_WIDGET (widget));
1821
1822   if (GTK_IS_RESIZE_CONTAINER (widget))
1823     gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
1824
1825   gtk_widget_queue_clear (widget);
1826
1827   if (widget->parent)
1828     gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
1829   else if (GTK_WIDGET_TOPLEVEL (widget))
1830     gtk_container_queue_resize (GTK_CONTAINER (widget));
1831 }
1832
1833 /*****************************************
1834  * gtk_widget_draw:
1835  *
1836  *   arguments:
1837  *
1838  *   results:
1839  *****************************************/
1840
1841 void
1842 gtk_widget_draw (GtkWidget    *widget,
1843                  GdkRectangle *area)
1844 {
1845   GdkRectangle temp_area;
1846
1847   g_return_if_fail (widget != NULL);
1848   g_return_if_fail (GTK_IS_WIDGET (widget));
1849
1850   if (GTK_WIDGET_DRAWABLE (widget))
1851     {
1852       if (area)
1853         {
1854           if (area->width <= 0 || area->height <= 0)
1855             return;
1856         }
1857       else
1858         {
1859           if (GTK_WIDGET_NO_WINDOW (widget))
1860             {
1861               temp_area.x = widget->allocation.x;
1862               temp_area.y = widget->allocation.y;
1863             }
1864           else
1865             {
1866               temp_area.x = 0;
1867               temp_area.y = 0;
1868             }
1869
1870           temp_area.width = widget->allocation.width;
1871           temp_area.height = widget->allocation.height;
1872           area = &temp_area;
1873         }
1874
1875       if (!GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_DOUBLE_BUFFERED (widget))
1876         {
1877           GdkRectangle tmp_area = *area;
1878           gint x, y;
1879
1880           if (!GTK_WIDGET_TOPLEVEL (widget))
1881             {
1882               gdk_window_get_position (widget->window, &x, &y);
1883               tmp_area.x -= x - widget->allocation.x;
1884               tmp_area.y -= y - widget->allocation.y;
1885             }
1886
1887           gdk_window_begin_paint_rect (widget->window, &tmp_area);
1888         }
1889       
1890       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area);
1891
1892       if (!GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_DOUBLE_BUFFERED (widget))
1893         gdk_window_end_paint (widget->window);
1894     }
1895 }
1896
1897 /*****************************************
1898  * gtk_widget_draw_focus:
1899  *
1900  *   arguments:
1901  *
1902  *   results:
1903  *****************************************/
1904
1905 void
1906 gtk_widget_draw_focus (GtkWidget *widget)
1907 {
1908   g_return_if_fail (widget != NULL);
1909   g_return_if_fail (GTK_IS_WIDGET (widget));
1910   
1911   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_FOCUS]);
1912 }
1913
1914 /*****************************************
1915  * gtk_widget_draw_default:
1916  *
1917  *   arguments:
1918  *
1919  *   results:
1920  *****************************************/
1921
1922 void
1923 gtk_widget_draw_default (GtkWidget *widget)
1924 {
1925   g_return_if_fail (widget != NULL);
1926   g_return_if_fail (GTK_IS_WIDGET (widget));
1927   
1928   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_DEFAULT]);
1929 }
1930
1931 /*****************************************
1932  * gtk_widget_size_request:
1933  *
1934  *   arguments:
1935  *
1936  *   results:
1937  *****************************************/
1938
1939 void
1940 gtk_widget_size_request (GtkWidget      *widget,
1941                          GtkRequisition *requisition)
1942 {
1943   g_return_if_fail (widget != NULL);
1944   g_return_if_fail (GTK_IS_WIDGET (widget));
1945
1946 #ifdef G_ENABLE_DEBUG
1947   if (requisition == &widget->requisition)
1948     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.");
1949 #endif /* G_ENABLE_DEBUG */
1950
1951   gtk_widget_ref (widget);
1952   gtk_widget_ensure_style (widget);
1953   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST],
1954                    &widget->requisition);
1955
1956   if (requisition)
1957     gtk_widget_get_child_requisition (widget, requisition);
1958
1959   gtk_widget_unref (widget);
1960 }
1961
1962 /*****************************************
1963  * gtk_widget_get_requesition:
1964  *
1965  *   arguments:
1966  *
1967  *   results:
1968  *****************************************/
1969
1970 void
1971 gtk_widget_get_child_requisition (GtkWidget      *widget,
1972                                   GtkRequisition *requisition)
1973 {
1974   GtkWidgetAuxInfo *aux_info;
1975
1976   g_return_if_fail (widget != NULL);
1977   g_return_if_fail (GTK_IS_WIDGET (widget));
1978
1979   *requisition = widget->requisition;
1980   
1981   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
1982   if (aux_info)
1983     {
1984       if (aux_info->width > 0)
1985         requisition->width = aux_info->width;
1986       if (aux_info->height > 0)
1987         requisition->height = aux_info->height;
1988     }
1989 }
1990
1991 /*****************************************
1992  * gtk_widget_size_allocate:
1993  *
1994  *   arguments:
1995  *
1996  *   results:
1997  *****************************************/
1998
1999 void
2000 gtk_widget_size_allocate (GtkWidget     *widget,
2001                           GtkAllocation *allocation)
2002 {
2003   GtkWidgetAuxInfo *aux_info;
2004   GtkAllocation real_allocation;
2005   gboolean needs_draw = FALSE;
2006   
2007   g_return_if_fail (widget != NULL);
2008   g_return_if_fail (GTK_IS_WIDGET (widget));
2009   
2010   real_allocation = *allocation;
2011   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
2012   
2013   if (aux_info)
2014     {
2015       if (aux_info->x != -1)
2016         real_allocation.x = aux_info->x;
2017       if (aux_info->y != -1)
2018         real_allocation.y = aux_info->y;
2019     }
2020
2021   real_allocation.width = MAX (real_allocation.width, 1);
2022   real_allocation.height = MAX (real_allocation.height, 1);
2023
2024   if (real_allocation.width < 0 || real_allocation.height < 0)
2025     {
2026       g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
2027                  real_allocation.width,
2028                  real_allocation.height);
2029       real_allocation.width = 1;
2030       real_allocation.height = 1;
2031     }
2032   
2033   if (GTK_WIDGET_NO_WINDOW (widget))
2034     {
2035       if (widget->allocation.x != real_allocation.x ||
2036           widget->allocation.y != real_allocation.y ||
2037           widget->allocation.width != real_allocation.width ||
2038           widget->allocation.height != real_allocation.height)
2039         {
2040           gtk_widget_queue_clear_child (widget);
2041           needs_draw = TRUE;
2042         }
2043     }
2044   else if (widget->allocation.width != real_allocation.width ||
2045            widget->allocation.height != real_allocation.height)
2046     {
2047       needs_draw = TRUE;
2048     }
2049
2050   if (GTK_IS_RESIZE_CONTAINER (widget))
2051     gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
2052
2053   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
2054
2055   if (needs_draw)
2056     {
2057       gtk_widget_queue_draw (widget);
2058       if (widget->parent && GTK_CONTAINER (widget->parent)->reallocate_redraws)
2059         gtk_widget_queue_draw (widget->parent);
2060     }
2061 }
2062
2063 static void
2064 gtk_widget_real_size_allocate (GtkWidget     *widget,
2065                                GtkAllocation *allocation)
2066 {
2067   g_return_if_fail (widget != NULL);
2068   g_return_if_fail (GTK_IS_WIDGET (widget));
2069
2070   widget->allocation = *allocation;
2071   
2072   if (GTK_WIDGET_REALIZED (widget) &&
2073       !GTK_WIDGET_NO_WINDOW (widget))
2074      {
2075         gdk_window_move_resize (widget->window,
2076                                 allocation->x, allocation->y,
2077                                 allocation->width, allocation->height);
2078      }
2079 }
2080
2081 static void
2082 gtk_widget_stop_add_accelerator (GtkWidget *widget)
2083 {
2084   g_return_if_fail (widget != NULL);
2085   g_return_if_fail (GTK_IS_WIDGET (widget));
2086
2087   gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[ADD_ACCELERATOR]);
2088 }
2089
2090 static void
2091 gtk_widget_stop_remove_accelerator (GtkWidget *widget)
2092 {
2093   g_return_if_fail (widget != NULL);
2094   g_return_if_fail (GTK_IS_WIDGET (widget));
2095
2096   gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR]);
2097 }
2098
2099 void
2100 gtk_widget_lock_accelerators (GtkWidget *widget)
2101 {
2102   g_return_if_fail (widget != NULL);
2103   g_return_if_fail (GTK_IS_WIDGET (widget));
2104   
2105   if (!gtk_widget_accelerators_locked (widget))
2106     {
2107       gtk_signal_connect (GTK_OBJECT (widget),
2108                           "add_accelerator",
2109                           GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2110                           NULL);
2111       gtk_signal_connect (GTK_OBJECT (widget),
2112                           "remove_accelerator",
2113                           GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2114                           NULL);
2115     }
2116 }
2117
2118 void
2119 gtk_widget_unlock_accelerators (GtkWidget *widget)
2120 {
2121   g_return_if_fail (widget != NULL);
2122   g_return_if_fail (GTK_IS_WIDGET (widget));
2123   
2124   if (gtk_widget_accelerators_locked (widget))
2125     {
2126       gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2127                                      GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2128                                      NULL);
2129       gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2130                                      GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2131                                      NULL);
2132     }
2133 }
2134
2135 gboolean
2136 gtk_widget_accelerators_locked (GtkWidget *widget)
2137 {
2138   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2139   
2140   return gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
2141                                              widget_signals[ADD_ACCELERATOR],
2142                                              TRUE,
2143                                              GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2144                                              NULL) > 0;
2145 }
2146
2147 void
2148 gtk_widget_add_accelerator (GtkWidget           *widget,
2149                             const gchar         *accel_signal,
2150                             GtkAccelGroup       *accel_group,
2151                             guint                accel_key,
2152                             guint                accel_mods,
2153                             GtkAccelFlags        accel_flags)
2154 {
2155   g_return_if_fail (widget != NULL);
2156   g_return_if_fail (GTK_IS_WIDGET (widget));
2157   g_return_if_fail (accel_group != NULL);
2158
2159   gtk_accel_group_add (accel_group,
2160                        accel_key,
2161                        accel_mods,
2162                        accel_flags,
2163                        (GtkObject*) widget,
2164                        accel_signal);
2165 }
2166
2167 void
2168 gtk_widget_remove_accelerator (GtkWidget           *widget,
2169                                GtkAccelGroup       *accel_group,
2170                                guint                accel_key,
2171                                guint                accel_mods)
2172 {
2173   g_return_if_fail (widget != NULL);
2174   g_return_if_fail (GTK_IS_WIDGET (widget));
2175   g_return_if_fail (accel_group != NULL);
2176
2177   gtk_accel_group_remove (accel_group,
2178                           accel_key,
2179                           accel_mods,
2180                           (GtkObject*) widget);
2181 }
2182
2183 void
2184 gtk_widget_remove_accelerators (GtkWidget           *widget,
2185                                 const gchar         *accel_signal,
2186                                 gboolean             visible_only)
2187 {
2188   GSList *slist;
2189   guint signal_id;
2190   
2191   g_return_if_fail (widget != NULL);
2192   g_return_if_fail (GTK_IS_WIDGET (widget));
2193   g_return_if_fail (accel_signal != NULL);
2194   
2195   signal_id = gtk_signal_lookup (accel_signal, GTK_OBJECT_TYPE (widget));
2196   g_return_if_fail (signal_id != 0);
2197   
2198   slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget));
2199   while (slist)
2200     {
2201       GtkAccelEntry *ac_entry;
2202       
2203       ac_entry = slist->data;
2204       slist = slist->next;
2205       if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE &&
2206           ac_entry->signal_id == signal_id)
2207         gtk_widget_remove_accelerator (GTK_WIDGET (widget),
2208                                        ac_entry->accel_group,
2209                                        ac_entry->accelerator_key,
2210                                        ac_entry->accelerator_mods);
2211     }
2212 }
2213
2214 guint
2215 gtk_widget_accelerator_signal (GtkWidget           *widget,
2216                                GtkAccelGroup       *accel_group,
2217                                guint                accel_key,
2218                                guint                accel_mods)
2219 {
2220   GtkAccelEntry *ac_entry;
2221
2222   g_return_val_if_fail (widget != NULL, 0);
2223   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
2224   g_return_val_if_fail (accel_group != NULL, 0);
2225
2226   ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods);
2227
2228   if (ac_entry && ac_entry->object == (GtkObject*) widget)
2229     return ac_entry->signal_id;
2230   return 0;
2231 }
2232
2233 static gint
2234 gtk_widget_real_key_press_event (GtkWidget         *widget,
2235                                  GdkEventKey       *event)
2236 {
2237   gboolean handled = FALSE;
2238
2239   g_return_val_if_fail (widget != NULL, handled);
2240   g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2241   g_return_val_if_fail (event != NULL, handled);
2242
2243   if (!handled)
2244     handled = gtk_bindings_activate (GTK_OBJECT (widget),
2245                                      event->keyval,
2246                                      event->state);
2247
2248   return handled;
2249 }
2250
2251 static gint
2252 gtk_widget_real_key_release_event (GtkWidget         *widget,
2253                                    GdkEventKey       *event)
2254 {
2255   gboolean handled = FALSE;
2256
2257   g_return_val_if_fail (widget != NULL, handled);
2258   g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2259   g_return_val_if_fail (event != NULL, handled);
2260
2261   if (!handled)
2262     handled = gtk_bindings_activate (GTK_OBJECT (widget),
2263                                      event->keyval,
2264                                      event->state | GDK_RELEASE_MASK);
2265
2266   return handled;
2267 }
2268
2269 /*****************************************
2270  * gtk_widget_event:
2271  *
2272  *   arguments:
2273  *
2274  *   results:
2275  *****************************************/
2276
2277 gint
2278 gtk_widget_event (GtkWidget *widget,
2279                   GdkEvent  *event)
2280 {
2281   gboolean return_val;
2282   gint signal_num;
2283
2284   g_return_val_if_fail (widget != NULL, TRUE);
2285   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
2286
2287   gtk_widget_ref (widget);
2288   return_val = FALSE;
2289   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event,
2290                    &return_val);
2291   if (return_val || GTK_OBJECT_DESTROYED (widget))
2292     goto out;
2293
2294   switch (event->type)
2295     {
2296     case GDK_NOTHING:
2297       signal_num = -1;
2298       break;
2299     case GDK_BUTTON_PRESS:
2300     case GDK_2BUTTON_PRESS:
2301     case GDK_3BUTTON_PRESS:
2302       signal_num = BUTTON_PRESS_EVENT;
2303       break;
2304     case GDK_SCROLL:
2305       signal_num = SCROLL_EVENT;
2306       break;
2307     case GDK_BUTTON_RELEASE:
2308       signal_num = BUTTON_RELEASE_EVENT;
2309       break;
2310     case GDK_MOTION_NOTIFY:
2311       signal_num = MOTION_NOTIFY_EVENT;
2312       break;
2313     case GDK_DELETE:
2314       signal_num = DELETE_EVENT;
2315       break;
2316     case GDK_DESTROY:
2317       signal_num = DESTROY_EVENT;
2318       break;
2319     case GDK_KEY_PRESS:
2320       signal_num = KEY_PRESS_EVENT;
2321       break;
2322     case GDK_KEY_RELEASE:
2323       signal_num = KEY_RELEASE_EVENT;
2324       break;
2325     case GDK_ENTER_NOTIFY:
2326       signal_num = ENTER_NOTIFY_EVENT;
2327       break;
2328     case GDK_LEAVE_NOTIFY:
2329       signal_num = LEAVE_NOTIFY_EVENT;
2330       break;
2331     case GDK_FOCUS_CHANGE:
2332       if (event->focus_change.in)
2333         signal_num = FOCUS_IN_EVENT;
2334       else
2335         signal_num = FOCUS_OUT_EVENT;
2336       break;
2337     case GDK_CONFIGURE:
2338       signal_num = CONFIGURE_EVENT;
2339       break;
2340     case GDK_MAP:
2341       signal_num = MAP_EVENT;
2342       break;
2343     case GDK_UNMAP:
2344       signal_num = UNMAP_EVENT;
2345       break;
2346     case GDK_PROPERTY_NOTIFY:
2347       signal_num = PROPERTY_NOTIFY_EVENT;
2348       break;
2349     case GDK_SELECTION_CLEAR:
2350       signal_num = SELECTION_CLEAR_EVENT;
2351       break;
2352     case GDK_SELECTION_REQUEST:
2353       signal_num = SELECTION_REQUEST_EVENT;
2354       break;
2355     case GDK_SELECTION_NOTIFY:
2356       signal_num = SELECTION_NOTIFY_EVENT;
2357       break;
2358     case GDK_PROXIMITY_IN:
2359       signal_num = PROXIMITY_IN_EVENT;
2360       break;
2361     case GDK_PROXIMITY_OUT:
2362       signal_num = PROXIMITY_OUT_EVENT;
2363       break;
2364     case GDK_NO_EXPOSE:
2365       signal_num = NO_EXPOSE_EVENT;
2366       break;
2367     case GDK_CLIENT_EVENT:
2368       signal_num = CLIENT_EVENT;
2369       break;
2370     case GDK_EXPOSE:
2371       if (!event->any.window)   /* Why is this necessary */
2372         goto out;
2373
2374       signal_num = EXPOSE_EVENT;
2375       break;
2376     case GDK_VISIBILITY_NOTIFY:
2377       signal_num = VISIBILITY_NOTIFY_EVENT;
2378       break;
2379     default:
2380       g_warning ("could not determine signal number for event: %d", event->type);
2381       goto out;
2382     }
2383   
2384   if (signal_num != -1)
2385     gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val);
2386
2387   return_val |= GTK_OBJECT_DESTROYED (widget);
2388
2389  out:
2390   gtk_widget_unref (widget);
2391
2392   return return_val;
2393 }
2394
2395 /*****************************************
2396  * gtk_widget_activate:
2397  *
2398  *   arguments:
2399  *
2400  *   results:
2401  *****************************************/
2402
2403 gboolean
2404 gtk_widget_activate (GtkWidget *widget)
2405 {
2406   g_return_val_if_fail (widget != NULL, FALSE);
2407   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2408   
2409   if (WIDGET_CLASS (widget)->activate_signal)
2410     {
2411       /* FIXME: we should eventually check the signals signature here */
2412       gtk_signal_emit (GTK_OBJECT (widget), WIDGET_CLASS (widget)->activate_signal);
2413
2414       return TRUE;
2415     }
2416   else
2417     return FALSE;
2418 }
2419
2420 gboolean
2421 gtk_widget_set_scroll_adjustments (GtkWidget     *widget,
2422                                    GtkAdjustment *hadjustment,
2423                                    GtkAdjustment *vadjustment)
2424 {
2425   g_return_val_if_fail (widget != NULL, FALSE);
2426   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2427   if (hadjustment)
2428     g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), FALSE);
2429   if (vadjustment)
2430     g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), FALSE);
2431
2432   if (WIDGET_CLASS (widget)->set_scroll_adjustments_signal)
2433     {
2434       /* FIXME: we should eventually check the signals signature here */
2435       gtk_signal_emit (GTK_OBJECT (widget),
2436                        WIDGET_CLASS (widget)->set_scroll_adjustments_signal,
2437                        hadjustment, vadjustment);
2438       return TRUE;
2439     }
2440   else
2441     return FALSE;
2442 }
2443
2444 /*****************************************
2445  * gtk_widget_reparent_container_child:
2446  *   assistent function to gtk_widget_reparent
2447  *
2448  *   arguments:
2449  *
2450  *   results:
2451  *****************************************/
2452
2453 static void
2454 gtk_widget_reparent_container_child (GtkWidget *widget,
2455                                      gpointer   client_data)
2456 {
2457   g_return_if_fail (widget != NULL);
2458   g_return_if_fail (GTK_IS_WIDGET (widget));
2459   g_return_if_fail (client_data != NULL);
2460   
2461   if (GTK_WIDGET_NO_WINDOW (widget))
2462     {
2463       if (widget->window)
2464         gdk_window_unref (widget->window);
2465       widget->window = (GdkWindow*) client_data;
2466       if (widget->window)
2467         gdk_window_ref (widget->window);
2468
2469       if (GTK_IS_CONTAINER (widget))
2470         gtk_container_forall (GTK_CONTAINER (widget),
2471                               gtk_widget_reparent_container_child,
2472                               client_data);
2473     }
2474   else
2475     gdk_window_reparent (widget->window, 
2476                          (GdkWindow*) client_data, 0, 0);
2477 }
2478
2479 /*****************************************
2480  * gtk_widget_reparent:
2481  *
2482  *   arguments:
2483  *
2484  *   results:
2485  *****************************************/
2486
2487 void
2488 gtk_widget_reparent (GtkWidget *widget,
2489                      GtkWidget *new_parent)
2490 {
2491   g_return_if_fail (widget != NULL);
2492   g_return_if_fail (GTK_IS_WIDGET (widget));
2493   g_return_if_fail (new_parent != NULL);
2494   g_return_if_fail (GTK_IS_CONTAINER (new_parent));
2495   g_return_if_fail (widget->parent != NULL);
2496   
2497   if (widget->parent != new_parent)
2498     {
2499       /* First try to see if we can get away without unrealizing
2500        * the widget as we reparent it. if so we set a flag so
2501        * that gtk_widget_unparent doesn't unrealize widget
2502        */
2503       if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
2504         GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
2505       
2506       gtk_widget_ref (widget);
2507       gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
2508       gtk_container_add (GTK_CONTAINER (new_parent), widget);
2509       gtk_widget_unref (widget);
2510       
2511       if (GTK_WIDGET_IN_REPARENT (widget))
2512         {
2513           GTK_PRIVATE_UNSET_FLAG (widget, GTK_IN_REPARENT);
2514           
2515           gtk_widget_reparent_container_child (widget,
2516                                                gtk_widget_get_parent_window (widget));
2517         }
2518     }
2519 }
2520
2521 /*****************************************
2522  * gtk_widget_popup:
2523  *
2524  *   arguments:
2525  *
2526  *   results:
2527  *****************************************/
2528
2529 void
2530 gtk_widget_popup (GtkWidget *widget,
2531                   gint       x,
2532                   gint       y)
2533 {
2534   g_return_if_fail (widget != NULL);
2535   g_return_if_fail (GTK_IS_WIDGET (widget));
2536   
2537   if (!GTK_WIDGET_VISIBLE (widget))
2538     {
2539       if (!GTK_WIDGET_REALIZED (widget))
2540         gtk_widget_realize (widget);
2541       if (!GTK_WIDGET_NO_WINDOW (widget))
2542         gdk_window_move (widget->window, x, y);
2543       gtk_widget_show (widget);
2544     }
2545 }
2546
2547 /*****************************************
2548  * gtk_widget_intersect:
2549  *
2550  *   arguments:
2551  *
2552  *   results:
2553  *****************************************/
2554
2555 gint
2556 gtk_widget_intersect (GtkWidget    *widget,
2557                       GdkRectangle *area,
2558                       GdkRectangle *intersection)
2559 {
2560   GdkRectangle *dest;
2561   GdkRectangle tmp;
2562   gint return_val;
2563   
2564   g_return_val_if_fail (widget != NULL, FALSE);
2565   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2566   g_return_val_if_fail (area != NULL, FALSE);
2567   
2568   if (intersection)
2569     dest = intersection;
2570   else
2571     dest = &tmp;
2572   
2573   return_val = gdk_rectangle_intersect (&widget->allocation, area, dest);
2574   
2575   if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
2576     {
2577       intersection->x -= widget->allocation.x;
2578       intersection->y -= widget->allocation.y;
2579     }
2580   
2581   return return_val;
2582 }
2583
2584 /*****************************************
2585  * gtk_widget_grab_focus:
2586  *
2587  *   arguments:
2588  *
2589  *   results:
2590  *****************************************/
2591
2592 void
2593 gtk_widget_grab_focus (GtkWidget *widget)
2594 {
2595   g_return_if_fail (widget != NULL);
2596   g_return_if_fail (GTK_IS_WIDGET (widget));
2597
2598   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[GRAB_FOCUS]);
2599 }
2600
2601 static void
2602 reset_focus_recurse (GtkWidget *widget,
2603                      gpointer   data)
2604 {
2605   if (GTK_IS_CONTAINER (widget))
2606     {
2607       GtkContainer *container;
2608
2609       container = GTK_CONTAINER (widget);
2610       gtk_container_set_focus_child (container, NULL);
2611
2612       gtk_container_foreach (container,
2613                              reset_focus_recurse,
2614                              NULL);
2615     }
2616 }
2617
2618 static void
2619 gtk_widget_real_grab_focus (GtkWidget *focus_widget)
2620 {
2621   g_return_if_fail (focus_widget != NULL);
2622   g_return_if_fail (GTK_IS_WIDGET (focus_widget));
2623   
2624   if (GTK_WIDGET_CAN_FOCUS (focus_widget))
2625     {
2626       GtkWidget *toplevel;
2627       GtkWidget *widget;
2628       
2629       /* clear the current focus setting, break if the current widget
2630        * is the focus widget's parent, since containers above that will
2631        * be set by the next loop.
2632        */
2633       toplevel = gtk_widget_get_toplevel (focus_widget);
2634       if (GTK_IS_WINDOW (toplevel))
2635         {
2636           widget = GTK_WINDOW (toplevel)->focus_widget;
2637           
2638           if (widget == focus_widget)
2639             {
2640               /* We call gtk_window_set_focus() here so that the
2641                * toplevel window can request the focus if necessary.
2642                * This is needed when the toplevel is a GtkPlug
2643                */
2644               if (!GTK_WIDGET_HAS_FOCUS (widget))
2645                 gtk_window_set_focus (GTK_WINDOW (toplevel), focus_widget);
2646
2647               return;
2648             }
2649           
2650           if (widget)
2651             {
2652               while (widget->parent && widget->parent != focus_widget->parent)
2653                 {
2654                   widget = widget->parent;
2655                   gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
2656                 }
2657             }
2658         }
2659       else if (toplevel != focus_widget)
2660         {
2661           /* gtk_widget_grab_focus() operates on a tree without window...
2662            * actually, this is very questionable behaviour.
2663            */
2664           
2665           gtk_container_foreach (GTK_CONTAINER (toplevel),
2666                                  reset_focus_recurse,
2667                                  NULL);
2668         }
2669
2670       /* now propagate the new focus up the widget tree and finally
2671        * set it on the window
2672        */
2673       widget = focus_widget;
2674       while (widget->parent)
2675         {
2676           gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), widget);
2677           widget = widget->parent;
2678         }
2679       if (GTK_IS_WINDOW (widget))
2680         gtk_window_set_focus (GTK_WINDOW (widget), focus_widget);
2681     }
2682 }
2683
2684 /*****************************************
2685  * gtk_widget_grab_default:
2686  *
2687  *   arguments:
2688  *
2689  *   results:
2690  *****************************************/
2691
2692 void
2693 gtk_widget_grab_default (GtkWidget *widget)
2694 {
2695   GtkWidget *window;
2696   GtkType window_type;
2697   
2698   g_return_if_fail (widget != NULL);
2699   g_return_if_fail (GTK_IS_WIDGET (widget));
2700   g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
2701   
2702   window_type = GTK_TYPE_WINDOW;
2703   window = widget->parent;
2704   
2705   while (window && !gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2706     window = window->parent;
2707   
2708   if (window && gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2709     gtk_window_set_default (GTK_WINDOW (window), widget);
2710   else
2711     g_warning("gtk_widget_grab_default() called on a widget not within a GtkWindow");
2712 }
2713
2714 /*****************************************
2715  * gtk_widget_set_name:
2716  *
2717  *   arguments:
2718  *
2719  *   results:
2720  *****************************************/
2721
2722 void
2723 gtk_widget_set_name (GtkWidget   *widget,
2724                      const gchar *name)
2725 {
2726   g_return_if_fail (widget != NULL);
2727   g_return_if_fail (GTK_IS_WIDGET (widget));
2728   
2729   if (widget->name)
2730     g_free (widget->name);
2731   widget->name = g_strdup (name);
2732
2733   if (GTK_WIDGET_RC_STYLE (widget))
2734     gtk_widget_set_rc_style (widget);
2735 }
2736
2737 /*****************************************
2738  * gtk_widget_get_name:
2739  *
2740  *   arguments:
2741  *
2742  *   results:
2743  *****************************************/
2744
2745 gchar*
2746 gtk_widget_get_name (GtkWidget *widget)
2747 {
2748   g_return_val_if_fail (widget != NULL, NULL);
2749   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2750   
2751   if (widget->name)
2752     return widget->name;
2753   return gtk_type_name (GTK_WIDGET_TYPE (widget));
2754 }
2755
2756 /*****************************************
2757  * gtk_widget_set_state:
2758  *
2759  *   arguments:
2760  *     widget
2761  *     state
2762  *
2763  *   results:
2764  *****************************************/
2765
2766 void
2767 gtk_widget_set_state (GtkWidget           *widget,
2768                       GtkStateType         state)
2769 {
2770   g_return_if_fail (widget != NULL);
2771   g_return_if_fail (GTK_IS_WIDGET (widget));
2772
2773   if (state == GTK_WIDGET_STATE (widget))
2774     return;
2775
2776   if (state == GTK_STATE_INSENSITIVE)
2777     gtk_widget_set_sensitive (widget, FALSE);
2778   else
2779     {
2780       GtkStateData data;
2781
2782       data.state = state;
2783       data.state_restoration = FALSE;
2784       data.use_forall = FALSE;
2785       if (widget->parent)
2786         data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
2787       else
2788         data.parent_sensitive = TRUE;
2789
2790       gtk_widget_propagate_state (widget, &data);
2791   
2792       if (GTK_WIDGET_DRAWABLE (widget))
2793         gtk_widget_queue_clear (widget);
2794     }
2795 }
2796
2797 void
2798 gtk_widget_set_app_paintable (GtkWidget *widget,
2799                               gboolean   app_paintable)
2800 {
2801   g_return_if_fail (widget != NULL);
2802   g_return_if_fail (GTK_IS_WIDGET (widget));
2803
2804   app_paintable = (app_paintable != FALSE);
2805
2806   if (GTK_WIDGET_APP_PAINTABLE (widget) != app_paintable)
2807     {
2808       if (app_paintable)
2809         GTK_WIDGET_SET_FLAGS (widget, GTK_APP_PAINTABLE);
2810       else
2811         GTK_WIDGET_UNSET_FLAGS (widget, GTK_APP_PAINTABLE);
2812
2813       if (GTK_WIDGET_DRAWABLE (widget))
2814         gtk_widget_queue_clear (widget);
2815     }
2816 }
2817
2818 void
2819 gtk_widget_set_double_buffered (GtkWidget *widget,
2820                                 gboolean   double_buffered)
2821 {
2822   g_return_if_fail (widget != NULL);
2823   g_return_if_fail (GTK_IS_WIDGET (widget));
2824
2825   if (double_buffered)
2826     GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
2827   else
2828     GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
2829 }
2830
2831 /*****************************************
2832  * gtk_widget_set_sensitive:
2833  *
2834  *   arguments:
2835  *     widget
2836  *     boolean value for sensitivity
2837  *
2838  *   results:
2839  *****************************************/
2840
2841 void
2842 gtk_widget_set_sensitive (GtkWidget *widget,
2843                           gboolean   sensitive)
2844 {
2845   GtkStateData data;
2846
2847   g_return_if_fail (widget != NULL);
2848   g_return_if_fail (GTK_IS_WIDGET (widget));
2849
2850   sensitive = (sensitive != FALSE);
2851
2852   if (sensitive == (GTK_WIDGET_SENSITIVE (widget) != FALSE))
2853     return;
2854
2855   if (sensitive)
2856     {
2857       GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
2858       data.state = GTK_WIDGET_SAVED_STATE (widget);
2859     }
2860   else
2861     {
2862       GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
2863       data.state = GTK_WIDGET_STATE (widget);
2864     }
2865   data.state_restoration = TRUE;
2866   data.use_forall = TRUE;
2867
2868   if (widget->parent)
2869     data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
2870   else
2871     data.parent_sensitive = TRUE;
2872
2873   gtk_widget_propagate_state (widget, &data);
2874   if (GTK_WIDGET_DRAWABLE (widget))
2875     gtk_widget_queue_clear (widget);
2876 }
2877
2878 /*****************************************
2879  * gtk_widget_set_parent:
2880  *
2881  *   arguments:
2882  *
2883  *   results:
2884  *****************************************/
2885
2886 void
2887 gtk_widget_set_parent (GtkWidget *widget,
2888                        GtkWidget *parent)
2889 {
2890   GtkStateData data;
2891   
2892   g_return_if_fail (widget != NULL);
2893   g_return_if_fail (GTK_IS_WIDGET (widget));
2894   g_return_if_fail (widget->parent == NULL);
2895   g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
2896   g_return_if_fail (parent != NULL);
2897   g_return_if_fail (GTK_IS_WIDGET (parent));
2898   g_return_if_fail (widget != parent);
2899
2900   /* keep this function in sync with gtk_menu_attach_to_widget()
2901    */
2902
2903   gtk_widget_ref (widget);
2904   gtk_object_sink (GTK_OBJECT (widget));
2905   widget->parent = parent;
2906
2907   if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL)
2908     data.state = GTK_WIDGET_STATE (parent);
2909   else
2910     data.state = GTK_WIDGET_STATE (widget);
2911   data.state_restoration = FALSE;
2912   data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (parent) != FALSE);
2913   data.use_forall = GTK_WIDGET_IS_SENSITIVE (parent) != GTK_WIDGET_IS_SENSITIVE (widget);
2914
2915   gtk_widget_propagate_state (widget, &data);
2916   
2917   gtk_widget_set_style_recurse (widget, NULL);
2918
2919   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], NULL);
2920 }
2921
2922 /*****************************************
2923  * Widget styles
2924  * see docs/styles.txt
2925  *****************************************/
2926 void
2927 gtk_widget_set_style (GtkWidget *widget,
2928                       GtkStyle  *style)
2929 {
2930   GtkStyle *default_style;
2931   gboolean initial_emission;
2932
2933   g_return_if_fail (widget != NULL);
2934   g_return_if_fail (GTK_IS_WIDGET (widget));
2935   g_return_if_fail (style != NULL);
2936
2937   initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
2938
2939   GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
2940   GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
2941
2942   default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
2943   if (!default_style)
2944     {
2945       gtk_style_ref (widget->style);
2946       if (!saved_default_style_key_id)
2947         saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
2948       gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
2949     }
2950
2951   gtk_widget_set_style_internal (widget, style, initial_emission);
2952 }
2953
2954 void
2955 gtk_widget_ensure_style (GtkWidget *widget)
2956 {
2957   g_return_if_fail (widget != NULL);
2958   g_return_if_fail (GTK_IS_WIDGET (widget));
2959
2960   if (!GTK_WIDGET_USER_STYLE (widget) &&
2961       !GTK_WIDGET_RC_STYLE (widget))
2962     gtk_widget_set_rc_style (widget);
2963 }
2964
2965 void
2966 gtk_widget_set_rc_style (GtkWidget *widget)
2967 {
2968   GtkStyle *saved_style;
2969   GtkStyle *new_style;
2970   gboolean initial_emission;
2971   
2972   g_return_if_fail (widget != NULL);
2973   g_return_if_fail (GTK_IS_WIDGET (widget));
2974
2975   initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
2976
2977   GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
2978   GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
2979
2980   saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
2981   new_style = gtk_rc_get_style (widget);
2982   if (new_style)
2983     {
2984       if (!saved_style)
2985         {
2986           gtk_style_ref (widget->style);
2987           if (!saved_default_style_key_id)
2988             saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
2989           gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
2990         }
2991       gtk_widget_set_style_internal (widget, new_style, initial_emission);
2992     }
2993   else
2994     {
2995       if (saved_style)
2996         {
2997           g_assert (initial_emission == FALSE); /* FIXME: remove this line */
2998
2999           gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3000           gtk_widget_set_style_internal (widget, saved_style, initial_emission);
3001           gtk_style_unref (saved_style);
3002         }
3003       else
3004         {
3005           if (initial_emission)
3006             gtk_widget_set_style_internal (widget, widget->style, TRUE);
3007         }
3008     }
3009 }
3010
3011 void
3012 gtk_widget_restore_default_style (GtkWidget *widget)
3013 {
3014   GtkStyle *default_style;
3015
3016   g_return_if_fail (widget != NULL);
3017   g_return_if_fail (GTK_IS_WIDGET (widget));
3018
3019   GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3020
3021   default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3022   if (default_style)
3023     {
3024       gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3025       gtk_widget_set_style_internal (widget, default_style, FALSE);
3026       gtk_style_unref (default_style);
3027     }
3028 }
3029
3030 GtkStyle*
3031 gtk_widget_get_style (GtkWidget *widget)
3032 {
3033   g_return_val_if_fail (widget != NULL, NULL);
3034   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3035   
3036   return widget->style;
3037 }
3038
3039 /**
3040  * gtk_widget_modify_style:
3041  * @widget: a #GtkWidget
3042  * @style: the #GtkRcStyle holding the style modifications
3043  * 
3044  * Modify style values on the widget. Modifications made using this
3045  * technique take precendence over style values set via an RC file,
3046  * however, they will be overriden if a style is explicitely set on
3047  * the widget using gtk_widget_set_style(). The #GtkRcStyle structure
3048  * is designed so each field can either be set or unset, so it is
3049  * possible, using this function, to modify some style values and
3050  * leave the others unchanged.
3051  *
3052  * Note that modifications made with this function are not cumulative
3053  * with previous calls to gtk_widget_modify_style() or with such
3054  * functions as gtk_widget_modify_fg(). If you wish to retain
3055  * previous values, you must first call gtk_widget_get_modifier_style(),
3056  * make your modifications to the returned style, then call
3057  * gtk_widget_modify_style() with that style. On the other hand,
3058  * if you first call gtk_widget_modify_style(), subsequent calls
3059  * to such functions gtk_widget_modify_fg() will be have a cumulative
3060  * effect with the inital modifications.
3061  **/
3062 void       
3063 gtk_widget_modify_style (GtkWidget      *widget,
3064                          GtkRcStyle     *style)
3065 {
3066   GtkRcStyle *old_style;
3067
3068   g_return_if_fail (GTK_IS_RC_STYLE (style));
3069   
3070   if (!rc_style_key_id)
3071     rc_style_key_id = g_quark_from_static_string (rc_style_key);
3072
3073   old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3074                                          rc_style_key_id);
3075
3076   if (style != old_style)
3077     gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3078                                     rc_style_key_id,
3079                                     gtk_rc_style_copy (style),
3080                                     (GtkDestroyNotify)gtk_rc_style_unref);
3081
3082   if (GTK_WIDGET_RC_STYLE (widget))
3083     gtk_widget_set_rc_style (widget);
3084 }
3085
3086 /**
3087  * gtk_widget_get_modifier_style:
3088  * @widget: a #GtkWidget
3089  * 
3090  * Return the current modifier style for the widget. (As set by
3091  * gtk_widget_modify_style().) If no style has previously set, a new
3092  * #GtkRcStyle will be created with all values unset, and set as the
3093  * modifier style for the widget. If you make changes to this rc
3094  * style, you must call gtk_widget_modify_style(), passing in the
3095  * returned rc style, to make sure that your changes take effect.
3096  * 
3097  * Return value: the modifier style for the widget. This rc style is
3098  *   owned by the widget. If you want to keep a pointer to value this
3099  *   around, you must add a refcount using gtk_rc_style_ref().
3100  **/
3101 GtkRcStyle *
3102 gtk_widget_get_modifier_style (GtkWidget      *widget)
3103 {
3104   GtkRcStyle *rc_style;
3105   
3106   if (!rc_style_key_id)
3107     rc_style_key_id = g_quark_from_static_string (rc_style_key);
3108   
3109   rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3110                                         rc_style_key_id);
3111
3112   if (!rc_style)
3113     {
3114       rc_style = gtk_rc_style_new();
3115       gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3116                                       rc_style_key_id,
3117                                       rc_style,
3118                                       (GtkDestroyNotify)gtk_rc_style_unref);
3119     }
3120
3121   return rc_style;
3122 }
3123
3124 static void
3125 gtk_widget_modify_color_component (GtkWidget     *widget,
3126                                    GtkRcFlags     component,
3127                                    GtkStateType   state,
3128                                    GdkColor      *color)
3129 {
3130   GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);  
3131
3132   switch (component)
3133     {
3134     case GTK_RC_FG:
3135       rc_style->fg[state] = *color;
3136       break;
3137     case GTK_RC_BG:
3138       rc_style->bg[state] = *color;
3139       break;
3140     case GTK_RC_TEXT:
3141       rc_style->text[state] = *color;
3142        break;
3143     case GTK_RC_BASE:
3144       rc_style->base[state] = *color;
3145       break;
3146     default:
3147       g_assert_not_reached();
3148     }
3149
3150   rc_style->color_flags[state] |= component;
3151
3152   if (GTK_WIDGET_RC_STYLE (widget))
3153     gtk_widget_set_rc_style (widget);
3154 }
3155
3156 /**
3157  * gtk_widget_modify_fg:
3158  * @widget: a #GtkWidget
3159  * @state: the state for which to set the foreground color.
3160  * @color: the color to assign (does not need to be allocated)
3161  * 
3162  * Set the foreground color for a widget in a particular state.  All
3163  * other style values are left untouched. See also
3164  * gtk_widget_modify_style().
3165  **/
3166 void
3167 gtk_widget_modify_fg (GtkWidget   *widget,
3168                       GtkStateType state,
3169                       GdkColor    *color)
3170 {
3171   g_return_if_fail (GTK_IS_WIDGET (widget));
3172   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
3173   g_return_if_fail (color != NULL);
3174
3175   gtk_widget_modify_color_component (widget, GTK_RC_FG, state, color);
3176 }
3177
3178 /**
3179  * gtk_widget_modify_bg:
3180  * @widget: a #GtkWidget
3181  * @state: the state for which to set the foreground color.
3182  * @color: the color to assign (does not need to be allocated)
3183  * 
3184  * Set the background color for a widget in a particular state.  All
3185  * other style values are left untouched. See also
3186  * gtk_widget_modify_style().
3187  **/
3188 void
3189 gtk_widget_modify_bg (GtkWidget   *widget,
3190                       GtkStateType state,
3191                       GdkColor    *color)
3192 {
3193   g_return_if_fail (GTK_IS_WIDGET (widget));
3194   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
3195   g_return_if_fail (color != NULL);
3196
3197   gtk_widget_modify_color_component (widget, GTK_RC_BG, state, color);
3198 }
3199
3200 /**
3201  * gtk_widget_modify_base:
3202  * @widget: a #GtkWidget
3203  * @state: the state for which to set the foreground color.
3204  * @color: the color to assign (does not need to be allocated)
3205  * 
3206  * Set the text color for a widget in a particular state.  All other
3207  * style values are left untouched. The text color is the foreground
3208  * color used along with the base color (see gtk_widget_modify_base)
3209  * for widgets such as #GtkEntry and #GtkTextView. See also
3210  * gtk_widget_modify_style().
3211  **/
3212 void
3213 gtk_widget_modify_text (GtkWidget   *widget,
3214                         GtkStateType state,
3215                         GdkColor    *color)
3216 {
3217   g_return_if_fail (GTK_IS_WIDGET (widget));
3218   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
3219   g_return_if_fail (color != NULL);
3220
3221   gtk_widget_modify_color_component (widget, GTK_RC_TEXT, state, color);
3222 }
3223
3224 /**
3225  * gtk_widget_modify_base:
3226  * @widget: a #GtkWidget
3227  * @state: the state for which to set the foreground color.
3228  * @color: the color to assign (does not need to be allocated)
3229  * 
3230  * Set the text color for a widget in a particular state.
3231  * All other style values are left untouched. The base color
3232  * is the background color used along with the text color
3233  * (see gtk_widget_modify_text) for widgets such as #GtkEntry
3234  * and #GtkTextView. See also gtk_widget_modify_style().
3235  **/
3236 void
3237 gtk_widget_modify_base (GtkWidget  *widget,
3238                         GtkStateType state,
3239                         GdkColor    *color)
3240 {
3241   g_return_if_fail (GTK_IS_WIDGET (widget));
3242   g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
3243   g_return_if_fail (color != NULL);
3244
3245   gtk_widget_modify_color_component (widget, GTK_RC_BASE, state, color);
3246 }
3247
3248 /**
3249  * gtk_widget_modify_font:
3250  * @widget: a #GtkWidget
3251  * @font_desc: the font description to use
3252  * 
3253  * Set the font to use for a widget.  All other style values are left
3254  * untouched. See also gtk_widget_modify_style().
3255  **/
3256 void
3257 gtk_widget_modify_font (GtkWidget            *widget,
3258                         PangoFontDescription *font_desc)
3259 {
3260   GtkRcStyle *rc_style;
3261
3262   g_return_if_fail (GTK_IS_WIDGET (widget));
3263   g_return_if_fail (font_desc != NULL);
3264
3265   rc_style = gtk_widget_get_modifier_style (widget);  
3266
3267   if (rc_style->font_desc)
3268     pango_font_description_free (rc_style->font_desc);
3269   
3270   rc_style->font_desc = pango_font_description_copy (font_desc);
3271   
3272   if (GTK_WIDGET_RC_STYLE (widget))
3273     gtk_widget_set_rc_style (widget);
3274 }
3275
3276 static void
3277 gtk_widget_direction_changed (GtkWidget        *widget,
3278                               GtkTextDirection  previous_direction)
3279 {
3280   gtk_widget_queue_resize (widget);
3281 }
3282
3283 static void
3284 gtk_widget_style_set (GtkWidget *widget,
3285                       GtkStyle  *previous_style)
3286 {
3287   if (GTK_WIDGET_REALIZED (widget) &&
3288       !GTK_WIDGET_NO_WINDOW (widget))
3289     gtk_style_set_background (widget->style, widget->window, widget->state);
3290 }
3291
3292 static void
3293 gtk_widget_set_style_internal (GtkWidget *widget,
3294                                GtkStyle  *style,
3295                                gboolean   initial_emission)
3296 {
3297   g_return_if_fail (widget != NULL);
3298   g_return_if_fail (GTK_IS_WIDGET (widget));
3299   g_return_if_fail (style != NULL);
3300
3301   if (widget->style != style || initial_emission)
3302     {
3303       PangoContext *context = gtk_widget_peek_pango_context (widget);
3304       if (context)
3305         pango_context_set_font_description (context, style->font_desc);
3306     }
3307   
3308   if (widget->style != style)
3309     {
3310       GtkStyle *previous_style;
3311
3312       if (GTK_WIDGET_REALIZED (widget))
3313         {
3314           gtk_widget_reset_shapes (widget);
3315           gtk_style_detach (widget->style);
3316         }
3317       
3318       previous_style = widget->style;
3319       widget->style = style;
3320       gtk_style_ref (widget->style);
3321       
3322       if (GTK_WIDGET_REALIZED (widget))
3323         widget->style = gtk_style_attach (widget->style, widget->window);
3324
3325       gtk_signal_emit (GTK_OBJECT (widget),
3326                        widget_signals[STYLE_SET],
3327                        initial_emission ? NULL : previous_style);
3328       gtk_style_unref (previous_style);
3329
3330       if (widget->parent && !initial_emission)
3331         {
3332           GtkRequisition old_requisition;
3333           
3334           old_requisition = widget->requisition;
3335           gtk_widget_size_request (widget, NULL);
3336           
3337           if ((old_requisition.width != widget->requisition.width) ||
3338               (old_requisition.height != widget->requisition.height))
3339             gtk_widget_queue_resize (widget);
3340           else if (GTK_WIDGET_DRAWABLE (widget))
3341             gtk_widget_queue_clear (widget);
3342         }
3343     }
3344   else if (initial_emission)
3345     {
3346       gtk_signal_emit (GTK_OBJECT (widget),
3347                        widget_signals[STYLE_SET],
3348                        NULL);
3349     }
3350 }
3351
3352 static void
3353 gtk_widget_set_style_recurse (GtkWidget *widget,
3354                               gpointer   client_data)
3355 {
3356   if (GTK_WIDGET_RC_STYLE (widget))
3357     gtk_widget_set_rc_style (widget);
3358   
3359   if (GTK_IS_CONTAINER (widget))
3360     gtk_container_forall (GTK_CONTAINER (widget),
3361                           gtk_widget_set_style_recurse,
3362                           NULL);
3363 }
3364
3365 void
3366 gtk_widget_reset_rc_styles (GtkWidget *widget)
3367 {
3368   g_return_if_fail (widget != NULL);
3369   g_return_if_fail (GTK_IS_WIDGET (widget));
3370
3371   gtk_widget_set_style_recurse (widget, NULL);
3372 }
3373
3374 void
3375 gtk_widget_set_default_style (GtkStyle *style)
3376 {
3377   if (style != gtk_default_style)
3378      {
3379        if (gtk_default_style)
3380          gtk_style_unref (gtk_default_style);
3381        gtk_default_style = style;
3382        if (gtk_default_style)
3383          gtk_style_ref (gtk_default_style);
3384      }
3385 }
3386
3387 GtkStyle*
3388 gtk_widget_get_default_style (void)
3389 {
3390   if (!gtk_default_style)
3391     {
3392       gtk_default_style = gtk_style_new ();
3393       gtk_style_ref (gtk_default_style);
3394     }
3395   
3396   return gtk_default_style;
3397 }
3398
3399 void
3400 gtk_widget_push_style (GtkStyle *style)
3401 {
3402   g_return_if_fail (style != NULL);
3403
3404   gtk_style_ref (style);
3405   style_stack = g_slist_prepend (style_stack, style);
3406 }
3407
3408 static GtkStyle*
3409 gtk_widget_peek_style (void)
3410 {
3411   if (style_stack)
3412     return (GtkStyle*) style_stack->data;
3413   else
3414     return gtk_widget_get_default_style ();
3415 }
3416
3417 void
3418 gtk_widget_pop_style (void)
3419 {
3420   GSList *tmp;
3421   
3422   if (style_stack)
3423     {
3424       tmp = style_stack;
3425       style_stack = style_stack->next;
3426       gtk_style_unref ((GtkStyle*) tmp->data);
3427       g_slist_free_1 (tmp);
3428     }
3429 }
3430
3431 static PangoContext *
3432 gtk_widget_peek_pango_context (GtkWidget *widget)
3433 {
3434   if (!pango_context_key_id)
3435     pango_context_key_id = g_quark_from_static_string (pango_context_key);
3436
3437   return gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
3438 }
3439
3440 /**
3441  * gtk_widget_get_pango_context:
3442  * @widget: a #GtkWidget
3443  * 
3444  * Get a #PangoContext with the appropriate colormap, font description
3445  * and base direction for this widget. Unlike the context returned
3446  * by gtk_widget_create_pango_context(), this context is owned by
3447  * the widget (it can be used as long as widget exists), and will
3448  * be updated to match any changes to the widget's attributes.
3449  *
3450  * If you create and keep a #PangoLayout using this context, you must
3451  * deal with changes to the context by calling pango_layout_context_changed()
3452  * on the layout in response to the ::style_set and ::direction_set signals
3453  * for the widget.
3454  *
3455  * Return value: the #PangoContext for the widget.
3456  **/
3457 PangoContext *
3458 gtk_widget_get_pango_context (GtkWidget *widget)
3459 {
3460   PangoContext *context;
3461
3462   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3463   
3464   if (!pango_context_key_id)
3465     pango_context_key_id = g_quark_from_static_string (pango_context_key);
3466
3467   context = gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
3468   if (!context)
3469     {
3470       context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
3471       gtk_object_set_data_by_id_full (GTK_OBJECT (widget), pango_context_key_id, context,
3472                                       (GDestroyNotify)g_object_unref);
3473     }
3474
3475   return context;
3476 }
3477
3478 /**
3479  * gtk_widget_create_pango_context:
3480  * @widget: a #PangoWidget
3481  * 
3482  * Create a new pango context with the appropriate colormap,
3483  * font description, and base direction for drawing text for
3484  * this widget. See also gtk_widget_get_pango_context()
3485  * 
3486  * Return value: the new #PangoContext
3487  **/
3488 PangoContext *
3489 gtk_widget_create_pango_context (GtkWidget *widget)
3490 {
3491   PangoContext *context;
3492   char *lang;
3493
3494   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3495
3496   context = gdk_pango_context_get ();
3497
3498   gdk_pango_context_set_colormap (context, gtk_widget_get_colormap (widget));
3499   pango_context_set_base_dir (context,
3500                               gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
3501                                 PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
3502   pango_context_set_font_description (context, widget->style->font_desc);
3503
3504   lang = gtk_get_default_language ();  
3505   pango_context_set_lang (context, lang);
3506   g_free (lang);
3507
3508   return context;
3509 }
3510
3511 /**
3512  * gtk_widget_create_pango_layout:
3513  * @widget: a #PangoWidget
3514  * @text:   text to set on the layout (can be %NULL)
3515  * 
3516  * Create a new #PangoLayout with the appropriate colormap,
3517  * font description, and base direction for drawing text for
3518  * this widget.
3519  *
3520  * If you keep a #PangoLayout created in this way around, in order
3521  * notify the layout of changes to the base direction or font of this
3522  * widget, you must call pango_layout_context_changed() in response to
3523  * the ::style_set and ::direction_set signals for the widget.
3524  * 
3525  * Return value: the new #PangoLayout
3526  **/
3527 PangoLayout *
3528 gtk_widget_create_pango_layout (GtkWidget   *widget,
3529                                 const gchar *text)
3530 {
3531   PangoLayout *layout;
3532   PangoContext *context;
3533
3534   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3535
3536   context = gtk_widget_get_pango_context (widget);
3537   layout = pango_layout_new (context);
3538
3539   if (text)
3540     pango_layout_set_text (layout, text, -1);
3541
3542   return layout;
3543 }
3544
3545 GdkPixbuf*
3546 gtk_widget_render_stock_icon (GtkWidget      *widget,
3547                               const gchar    *stock_id,
3548                               const gchar    *size,
3549                               const gchar    *detail)
3550 {
3551   GtkIconSet *icon_set;
3552   GdkPixbuf *retval;
3553   
3554   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3555   g_return_val_if_fail (stock_id != NULL, NULL);
3556   g_return_val_if_fail (size != NULL, NULL);
3557   
3558   gtk_widget_ensure_style (widget);
3559   
3560   icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
3561
3562   if (icon_set == NULL)
3563     return NULL;
3564
3565   retval = gtk_icon_set_render_icon (icon_set,
3566                                      widget->style,
3567                                      gtk_widget_get_direction (widget),
3568                                      GTK_WIDGET_STATE (widget),
3569                                      size,
3570                                      widget,
3571                                      detail);
3572
3573   return retval;
3574 }
3575
3576 /*************************************************************
3577  * gtk_widget_set_parent_window:
3578  *     Set a non default parent window for widget
3579  *
3580  *   arguments:
3581  *     widget:
3582  *     parent_window 
3583  *     
3584  *   results:
3585  *************************************************************/
3586
3587 void
3588 gtk_widget_set_parent_window   (GtkWidget           *widget,
3589                                 GdkWindow           *parent_window)
3590 {
3591   GdkWindow *old_parent_window;
3592
3593   g_return_if_fail (widget != NULL);
3594   g_return_if_fail (GTK_IS_WIDGET (widget));
3595   
3596   old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3597                                                  parent_window_key_id);
3598
3599   if (parent_window != old_parent_window)
3600     {
3601       if (!parent_window_key_id)
3602         parent_window_key_id = g_quark_from_static_string (parent_window_key);
3603       gtk_object_set_data_by_id (GTK_OBJECT (widget), parent_window_key_id, 
3604                                  parent_window);
3605       if (old_parent_window)
3606         gdk_window_unref (old_parent_window);
3607       if (parent_window)
3608         gdk_window_ref (parent_window);
3609     }
3610 }
3611
3612 /*************************************************************
3613  * gtk_widget_get_parent_window:
3614  *     Get widget's parent window
3615  *
3616  *   arguments:
3617  *     widget:
3618  *     
3619  *   results:
3620  *     parent window
3621  *************************************************************/
3622
3623 GdkWindow *
3624 gtk_widget_get_parent_window   (GtkWidget           *widget)
3625 {
3626   GdkWindow *parent_window;
3627
3628   g_return_val_if_fail (widget != NULL, NULL);
3629   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3630   g_return_val_if_fail (widget->parent != NULL, NULL);
3631   
3632   parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3633                                              parent_window_key_id);
3634
3635   return (parent_window != NULL) ? parent_window : widget->parent->window;
3636 }
3637
3638 /*****************************************
3639  * gtk_widget_set_uposition:
3640  *
3641  *   arguments:
3642  *
3643  *   results:
3644  *****************************************/
3645
3646 void
3647 gtk_widget_set_uposition (GtkWidget *widget,
3648                           gint       x,
3649                           gint       y)
3650 {
3651   GtkWidgetAuxInfo *aux_info;
3652   
3653   g_return_if_fail (widget != NULL);
3654   g_return_if_fail (GTK_IS_WIDGET (widget));
3655   
3656   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3657   if (!aux_info)
3658     {
3659       if (!aux_info_key_id)
3660         aux_info_key_id = g_quark_from_static_string (aux_info_key);
3661       aux_info = gtk_widget_aux_info_new ();
3662       gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3663     }
3664
3665   /* keep this in sync with gtk_window_compute_reposition() */
3666   
3667   if (x > -2)
3668     aux_info->x = x;
3669   if (y > -2)
3670     aux_info->y = y;
3671   
3672   if (GTK_IS_WINDOW (widget) && (aux_info->x != -1) && (aux_info->y != -1))
3673     gtk_window_reposition (GTK_WINDOW (widget), x, y);
3674   
3675   if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
3676     gtk_widget_size_allocate (widget, &widget->allocation);
3677 }
3678
3679 /*****************************************
3680  * gtk_widget_set_usize:
3681  *
3682  *   arguments:
3683  *
3684  *   results:
3685  *****************************************/
3686
3687 void
3688 gtk_widget_set_usize (GtkWidget *widget,
3689                       gint       width,
3690                       gint       height)
3691 {
3692   GtkWidgetAuxInfo *aux_info;
3693   
3694   g_return_if_fail (widget != NULL);
3695   g_return_if_fail (GTK_IS_WIDGET (widget));
3696   
3697   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3698   if (!aux_info)
3699     {
3700       if (!aux_info_key_id)
3701         aux_info_key_id = g_quark_from_static_string (aux_info_key);
3702       aux_info = gtk_widget_aux_info_new ();
3703       gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3704     }
3705   
3706   if (width > -2)
3707     aux_info->width = width;
3708   if (height > -2)
3709     aux_info->height = height;
3710   
3711   if (GTK_WIDGET_VISIBLE (widget))
3712     gtk_widget_queue_resize (widget);
3713 }
3714
3715 /*****************************************
3716  * gtk_widget_set_events:
3717  *
3718  *   arguments:
3719  *
3720  *   results:
3721  *****************************************/
3722
3723 void
3724 gtk_widget_set_events (GtkWidget *widget,
3725                        gint       events)
3726 {
3727   gint *eventp;
3728   
3729   g_return_if_fail (widget != NULL);
3730   g_return_if_fail (GTK_IS_WIDGET (widget));
3731   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3732   g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
3733   
3734   eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3735   
3736   if (events)
3737     {
3738       if (!eventp)
3739         eventp = g_new (gint, 1);
3740       
3741       *eventp = events;
3742       if (!event_key_id)
3743         event_key_id = g_quark_from_static_string (event_key);
3744       gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3745     }
3746   else if (eventp)
3747     {
3748       g_free (eventp);
3749       gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3750     }
3751 }
3752
3753 /*****************************************
3754  * gtk_widget_add_events:
3755  *
3756  *   arguments:
3757  *
3758  *   results:
3759  *****************************************/
3760
3761 void
3762 gtk_widget_add_events (GtkWidget *widget,
3763                        gint       events)
3764 {
3765   gint *eventp;
3766   
3767   g_return_if_fail (widget != NULL);
3768   g_return_if_fail (GTK_IS_WIDGET (widget));
3769   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3770   
3771   eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3772   
3773   if (events)
3774     {
3775       if (!eventp)
3776         {
3777           eventp = g_new (gint, 1);
3778           *eventp = 0;
3779         }
3780       
3781       *eventp |= events;
3782       if (!event_key_id)
3783         event_key_id = g_quark_from_static_string (event_key);
3784       gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3785     }
3786   else if (eventp)
3787     {
3788       g_free (eventp);
3789       gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3790     }
3791
3792   if (GTK_WIDGET_REALIZED (widget))
3793     {
3794       gdk_window_set_events (widget->window,
3795                              gdk_window_get_events (widget->window) | events);
3796     }
3797 }
3798
3799 /*****************************************
3800  * gtk_widget_set_extension_events:
3801  *
3802  *   arguments:
3803  *
3804  *   results:
3805  *****************************************/
3806
3807 void
3808 gtk_widget_set_extension_events (GtkWidget *widget,
3809                                  GdkExtensionMode mode)
3810 {
3811   GdkExtensionMode *modep;
3812   
3813   g_return_if_fail (widget != NULL);
3814   g_return_if_fail (GTK_IS_WIDGET (widget));
3815   
3816   modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3817   
3818   if (!modep)
3819     modep = g_new (GdkExtensionMode, 1);
3820   
3821   *modep = mode;
3822   if (!extension_event_key_id)
3823     extension_event_key_id = g_quark_from_static_string (extension_event_key);
3824   gtk_object_set_data_by_id (GTK_OBJECT (widget), extension_event_key_id, modep);
3825 }
3826
3827 /*****************************************
3828  * gtk_widget_get_toplevel:
3829  *
3830  *   arguments:
3831  *
3832  *   results:
3833  *****************************************/
3834
3835 GtkWidget*
3836 gtk_widget_get_toplevel (GtkWidget *widget)
3837 {
3838   g_return_val_if_fail (widget != NULL, NULL);
3839   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3840   
3841   while (widget->parent)
3842     widget = widget->parent;
3843   
3844   return widget;
3845 }
3846
3847 /*****************************************
3848  * gtk_widget_get_ancestor:
3849  *
3850  *   arguments:
3851  *
3852  *   results:
3853  *****************************************/
3854
3855 GtkWidget*
3856 gtk_widget_get_ancestor (GtkWidget *widget,
3857                          GtkType    widget_type)
3858 {
3859   g_return_val_if_fail (widget != NULL, NULL);
3860   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3861   
3862   while (widget && !gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type))
3863     widget = widget->parent;
3864   
3865   if (!(widget && gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type)))
3866     return NULL;
3867   
3868   return widget;
3869 }
3870
3871 /*****************************************
3872  * gtk_widget_get_colormap:
3873  *
3874  *   arguments:
3875  *
3876  *   results:
3877  *****************************************/
3878
3879 GdkColormap*
3880 gtk_widget_get_colormap (GtkWidget *widget)
3881 {
3882   GdkColormap *colormap;
3883   
3884   g_return_val_if_fail (widget != NULL, NULL);
3885   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3886   
3887   if (widget->window)
3888     {
3889       colormap = gdk_window_get_colormap (widget->window);
3890       /* If window was destroyed previously, we'll get NULL here */
3891       if (colormap)
3892         return colormap;
3893     }
3894   
3895   colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
3896   if (colormap)
3897     return colormap;
3898
3899   return gtk_widget_get_default_colormap ();
3900 }
3901
3902 /*****************************************
3903  * gtk_widget_get_visual:
3904  *
3905  *   arguments:
3906  *
3907  *   results:
3908  *****************************************/
3909
3910 GdkVisual*
3911 gtk_widget_get_visual (GtkWidget *widget)
3912 {
3913   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3914
3915   return gdk_colormap_get_visual (gtk_widget_get_colormap (widget));
3916 }
3917
3918 /*****************************************
3919  * gtk_widget_set_colormap:
3920  *    Set the colormap for the widget to the given
3921  *    value. Widget must not have been previously
3922  *    realized. This probably should only be used
3923  *    from an init() function.
3924  *   arguments:
3925  *    widget:
3926  *    colormap:
3927  *   results:
3928  *****************************************/
3929
3930 void
3931 gtk_widget_set_colormap (GtkWidget *widget, GdkColormap *colormap)
3932 {
3933   g_return_if_fail (widget != NULL);
3934   g_return_if_fail (GTK_IS_WIDGET (widget));
3935   g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
3936   g_return_if_fail (colormap != NULL);
3937
3938   /* FIXME: reference count the colormap.
3939    */
3940   
3941   gtk_object_set_data (GTK_OBJECT (widget), 
3942                        colormap_key,
3943                        colormap);
3944 }
3945
3946 /*****************************************
3947  * gtk_widget_get_events:
3948  *
3949  *   arguments:
3950  *
3951  *   results:
3952  *****************************************/
3953
3954 gint
3955 gtk_widget_get_events (GtkWidget *widget)
3956 {
3957   gint *events;
3958   
3959   g_return_val_if_fail (widget != NULL, 0);
3960   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3961   
3962   events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3963   if (events)
3964     return *events;
3965   
3966   return 0;
3967 }
3968
3969 /*****************************************
3970  * gtk_widget_get_extension_events:
3971  *
3972  *   arguments:
3973  *
3974  *   results:
3975  *****************************************/
3976
3977 GdkExtensionMode
3978 gtk_widget_get_extension_events (GtkWidget *widget)
3979 {
3980   GdkExtensionMode *mode;
3981   
3982   g_return_val_if_fail (widget != NULL, 0);
3983   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3984   
3985   mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3986   if (mode)
3987     return *mode;
3988   
3989   return 0;
3990 }
3991
3992 /*****************************************
3993  * gtk_widget_get_pointer:
3994  *
3995  *   arguments:
3996  *
3997  *   results:
3998  *****************************************/
3999
4000 void
4001 gtk_widget_get_pointer (GtkWidget *widget,
4002                         gint      *x,
4003                         gint      *y)
4004 {
4005   g_return_if_fail (widget != NULL);
4006   g_return_if_fail (GTK_IS_WIDGET (widget));
4007   
4008   if (x)
4009     *x = -1;
4010   if (y)
4011     *y = -1;
4012   
4013   if (GTK_WIDGET_REALIZED (widget))
4014     {
4015       gdk_window_get_pointer (widget->window, x, y, NULL);
4016       
4017       if (GTK_WIDGET_NO_WINDOW (widget))
4018         {
4019           if (x)
4020             *x -= widget->allocation.x;
4021           if (y)
4022             *y -= widget->allocation.y;
4023         }
4024     }
4025 }
4026
4027 /*****************************************
4028  * gtk_widget_is_ancestor:
4029  *
4030  *   arguments:
4031  *
4032  *   results:
4033  *****************************************/
4034
4035 gint
4036 gtk_widget_is_ancestor (GtkWidget *widget,
4037                         GtkWidget *ancestor)
4038 {
4039   g_return_val_if_fail (widget != NULL, FALSE);
4040   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4041   g_return_val_if_fail (ancestor != NULL, FALSE);
4042   
4043   while (widget)
4044     {
4045       if (widget->parent == ancestor)
4046         return TRUE;
4047       widget = widget->parent;
4048     }
4049   
4050   return FALSE;
4051 }
4052
4053 static GQuark quark_composite_name = 0;
4054
4055 void
4056 gtk_widget_set_composite_name (GtkWidget   *widget,
4057                                const gchar *name)
4058 {
4059   g_return_if_fail (widget != NULL);
4060   g_return_if_fail (GTK_IS_WIDGET (widget));
4061   g_return_if_fail (GTK_WIDGET_COMPOSITE_CHILD (widget));
4062   g_return_if_fail (name != NULL);
4063
4064   if (!quark_composite_name)
4065     quark_composite_name = g_quark_from_static_string ("gtk-composite-name");
4066
4067   gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
4068                                   quark_composite_name,
4069                                   g_strdup (name),
4070                                   g_free);
4071 }
4072
4073 gchar*
4074 gtk_widget_get_composite_name (GtkWidget *widget)
4075 {
4076   g_return_val_if_fail (widget != NULL, NULL);
4077   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4078
4079   if (GTK_WIDGET_COMPOSITE_CHILD (widget) && widget->parent)
4080     return gtk_container_child_composite_name (GTK_CONTAINER (widget->parent),
4081                                                widget);
4082   else
4083     return NULL;
4084 }
4085
4086 void
4087 gtk_widget_push_composite_child (void)
4088 {
4089   composite_child_stack++;
4090 }
4091
4092 void
4093 gtk_widget_pop_composite_child (void)
4094 {
4095   if (composite_child_stack)
4096     composite_child_stack--;
4097 }
4098
4099 /*****************************************
4100  * gtk_widget_push_colormap:
4101  *
4102  *   arguments:
4103  *
4104  *   results:
4105  *****************************************/
4106
4107 void
4108 gtk_widget_push_colormap (GdkColormap *cmap)
4109 {
4110   g_return_if_fail (cmap != NULL);
4111
4112   colormap_stack = g_slist_prepend (colormap_stack, cmap);
4113 }
4114
4115 /*****************************************
4116  * gtk_widget_pop_colormap:
4117  *
4118  *   arguments:
4119  *
4120  *   results:
4121  *****************************************/
4122
4123 void
4124 gtk_widget_pop_colormap (void)
4125 {
4126   GSList *tmp;
4127   
4128   if (colormap_stack)
4129     {
4130       tmp = colormap_stack;
4131       colormap_stack = colormap_stack->next;
4132       g_slist_free_1 (tmp);
4133     }
4134 }
4135
4136 /*****************************************
4137  * gtk_widget_set_default_colormap:
4138  *
4139  *   arguments:
4140  *
4141  *   results:
4142  *****************************************/
4143
4144 void
4145 gtk_widget_set_default_colormap (GdkColormap *colormap)
4146 {
4147   if (default_colormap != colormap)
4148     {
4149       if (default_colormap)
4150         gdk_colormap_unref (default_colormap);
4151       default_colormap = colormap;
4152       if (default_colormap)
4153         gdk_colormap_ref (default_colormap);
4154     }
4155 }
4156
4157 /*****************************************
4158  * gtk_widget_get_default_colormap:
4159  *
4160  *   arguments:
4161  *
4162  *   results:
4163  *****************************************/
4164
4165 GdkColormap*
4166 gtk_widget_get_default_colormap (void)
4167 {
4168   if (!default_colormap)
4169     default_colormap = gdk_colormap_get_system ();
4170   
4171   return default_colormap;
4172 }
4173
4174 /*****************************************
4175  * gtk_widget_get_default_visual:
4176  *
4177  *   arguments:
4178  *
4179  *   results:
4180  *****************************************/
4181
4182 GdkVisual*
4183 gtk_widget_get_default_visual (void)
4184 {
4185   return gdk_colormap_get_visual (gtk_widget_get_default_colormap ());
4186 }
4187
4188 static void
4189 gtk_widget_emit_direction_changed (GtkWidget        *widget,
4190                                    GtkTextDirection  old_dir)
4191 {
4192   PangoContext *context = gtk_widget_peek_pango_context (widget);
4193
4194   if (context)
4195     pango_context_set_base_dir (context,
4196                                 gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
4197                                   PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
4198   
4199   gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DIRECTION_CHANGED], old_dir);
4200 }
4201
4202 /**
4203  * gtk_widget_set_direction:
4204  * @widget: a #GtkWidget
4205  * @dir:    the new direction
4206  * 
4207  * Set the reading direction on a particular widget. This direction
4208  * controls the primary direction for widgets containing text,
4209  * and also the direction in which the children of a container are
4210  * packed. The ability to set the direction is present in order
4211  * so that correct localization into languages with right-to-left
4212  * reading directions can be done. Generally, applications will
4213  * let the default reading direction present, except for containers
4214  * where the containers are arranged in an order that is explicitely
4215  * visual rather than logical (such as buttons for text justificiation).
4216  *
4217  * If the direction is set to %GTK_TEXT_DIR_NONE, then the value
4218  * set by gtk_widget_set_default_direction() will be used.
4219  **/
4220 void
4221 gtk_widget_set_direction (GtkWidget        *widget,
4222                           GtkTextDirection  dir)
4223 {
4224   GtkTextDirection old_dir;
4225   
4226   g_return_if_fail (widget != NULL);
4227   g_return_if_fail (GTK_IS_WIDGET (widget));
4228   g_return_if_fail (dir >= GTK_TEXT_DIR_NONE && dir <= GTK_TEXT_DIR_RTL);
4229
4230   old_dir = gtk_widget_get_direction (widget);
4231   
4232   if (dir == GTK_TEXT_DIR_NONE)
4233     GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_SET);
4234   else
4235     {
4236       GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_SET);
4237       if (dir == GTK_TEXT_DIR_LTR)
4238         GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_LTR);
4239       else
4240         GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_LTR);
4241     }
4242
4243   if (old_dir != gtk_widget_get_direction (widget))
4244     gtk_widget_emit_direction_changed (widget, old_dir);
4245 }
4246
4247 /**
4248  * gtk_widget_get_direction:
4249  * @widget: a #GtkWidget
4250  * 
4251  * Get the reading direction for a particular widget. See
4252  * gtk_widget_set_direction().
4253  * 
4254  * Return value: the reading direction for the widget.
4255  **/
4256 GtkTextDirection
4257 gtk_widget_get_direction (GtkWidget *widget)
4258 {
4259   g_return_val_if_fail (widget != NULL, GTK_TEXT_DIR_LTR);
4260   g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_TEXT_DIR_LTR);
4261   
4262   if (GTK_WIDGET_DIRECTION_SET (widget))
4263     return GTK_WIDGET_DIRECTION_LTR (widget) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
4264   else
4265     return gtk_default_direction;
4266 }
4267
4268 static void
4269 gtk_widget_set_default_direction_recurse (GtkWidget *widget, gpointer data)
4270 {
4271   GtkTextDirection old_dir = GPOINTER_TO_UINT (data);
4272
4273   g_object_ref (G_OBJECT (widget));
4274   
4275   if (!GTK_WIDGET_DIRECTION_SET (widget))
4276     gtk_widget_emit_direction_changed (widget, old_dir);
4277   
4278   if (GTK_IS_CONTAINER (widget))
4279     gtk_container_forall (GTK_CONTAINER (widget),
4280                           gtk_widget_set_default_direction_recurse,
4281                           data);
4282
4283   g_object_unref (G_OBJECT (widget));
4284 }
4285
4286 /**
4287  * gtk_widget_set_default_direction:
4288  * @dir: the new default direction. This cannot be
4289  *        %GTK_TEXT_DIR_NONE.
4290  * 
4291  * Set the default reading direction for widgets where the
4292  * direction has not been explicitly set by gtk_widget_set_direction().
4293  **/
4294 void
4295 gtk_widget_set_default_direction (GtkTextDirection dir)
4296 {
4297   g_return_if_fail (dir == GTK_TEXT_DIR_RTL || dir == GTK_TEXT_DIR_LTR);
4298
4299   if (dir != gtk_default_direction)
4300     {
4301       GList *toplevels, *tmp_list;
4302       GtkTextDirection old_dir = gtk_default_direction;
4303       
4304       gtk_default_direction = dir;
4305
4306       tmp_list = toplevels = gtk_window_list_toplevels ();
4307       while (tmp_list)
4308         {
4309           gtk_widget_set_default_direction_recurse (tmp_list->data,
4310                                                     GUINT_TO_POINTER (old_dir));
4311           g_object_unref (tmp_list->data);
4312           tmp_list = tmp_list->next;
4313         }
4314
4315       g_list_free (toplevels);
4316       
4317     }
4318 }
4319
4320 /**
4321  * gtk_widget_get_default_direction:
4322  * 
4323  * Return value: the current default direction. See
4324  * gtk_widget_set_direction().
4325  **/
4326 GtkTextDirection
4327 gtk_widget_get_default_direction (void)
4328 {
4329   return gtk_default_direction;
4330 }
4331
4332 static void
4333 gtk_widget_shutdown (GObject *object)
4334 {
4335   GtkWidget *widget = GTK_WIDGET (object);
4336
4337   if (widget->parent)
4338     gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
4339
4340   GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4341   if (GTK_WIDGET_REALIZED (widget))
4342     gtk_widget_unrealize (widget);
4343   
4344   G_OBJECT_CLASS (parent_class)->shutdown (object);
4345 }
4346
4347 static void
4348 gtk_widget_real_destroy (GtkObject *object)
4349 {
4350   GtkWidget *widget;
4351   GtkStyle *saved_style;
4352
4353   /* gtk_object_destroy() will already hold a refcount on object
4354    */
4355   widget = GTK_WIDGET (object);
4356
4357   gtk_grab_remove (widget);
4358   gtk_selection_remove_all (widget);
4359   
4360   saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id);
4361   if (saved_style)
4362     {
4363       gtk_style_unref (saved_style);
4364       gtk_object_remove_data_by_id (object, saved_default_style_key_id);
4365     }
4366
4367   gtk_style_unref (widget->style);
4368   widget->style = gtk_widget_peek_style ();
4369   gtk_style_ref (widget->style);
4370
4371   GTK_OBJECT_CLASS (parent_class)->destroy (object);
4372 }
4373
4374 static void
4375 gtk_widget_finalize (GObject *object)
4376 {
4377   GtkWidget *widget = GTK_WIDGET (object);
4378   GtkWidgetAuxInfo *aux_info;
4379   gint *events;
4380   GdkExtensionMode *mode;
4381   GtkStyle *saved_style;
4382   
4383   gtk_grab_remove (widget);
4384   gtk_selection_remove_all (widget);
4385
4386   saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
4387   if (saved_style)
4388     {
4389       gtk_style_unref (saved_style);
4390       gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
4391     }
4392
4393   gtk_style_unref (widget->style);
4394   widget->style = NULL;
4395
4396   if (widget->name)
4397     g_free (widget->name);
4398   
4399   aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
4400   if (aux_info)
4401     gtk_widget_aux_info_destroy (aux_info);
4402   
4403   events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
4404   if (events)
4405     g_free (events);
4406   
4407   mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
4408   if (mode)
4409     g_free (mode);
4410
4411   G_OBJECT_CLASS (parent_class)->finalize (object);
4412 }
4413
4414 /*****************************************
4415  * gtk_widget_real_map:
4416  *
4417  *   arguments:
4418  *
4419  *   results:
4420  *****************************************/
4421
4422 static void
4423 gtk_widget_real_map (GtkWidget *widget)
4424 {
4425   g_return_if_fail (GTK_IS_WIDGET (widget));
4426   g_return_if_fail (GTK_WIDGET_REALIZED (widget) == TRUE);
4427   
4428   if (!GTK_WIDGET_MAPPED (widget))
4429     {
4430       GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4431       
4432       if (!GTK_WIDGET_NO_WINDOW (widget))
4433         gdk_window_show (widget->window);
4434     }
4435 }
4436
4437 /*****************************************
4438  * gtk_widget_real_unmap:
4439  *
4440  *   arguments:
4441  *
4442  *   results:
4443  *****************************************/
4444
4445 static void
4446 gtk_widget_real_unmap (GtkWidget *widget)
4447 {
4448   g_return_if_fail (widget != NULL);
4449   g_return_if_fail (GTK_IS_WIDGET (widget));
4450   
4451   if (GTK_WIDGET_MAPPED (widget))
4452     {
4453       GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4454
4455       if (!GTK_WIDGET_NO_WINDOW (widget))
4456         gdk_window_hide (widget->window);
4457     }
4458 }
4459
4460 /*****************************************
4461  * gtk_widget_real_realize:
4462  *
4463  *   arguments:
4464  *
4465  *   results:
4466  *****************************************/
4467
4468 static void
4469 gtk_widget_real_realize (GtkWidget *widget)
4470 {
4471   g_return_if_fail (widget != NULL);
4472   g_return_if_fail (GTK_IS_WIDGET (widget));
4473   g_return_if_fail (GTK_WIDGET_NO_WINDOW (widget));
4474   
4475   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4476   if (widget->parent)
4477     {
4478       widget->window = gtk_widget_get_parent_window (widget);
4479       gdk_window_ref (widget->window);
4480     }
4481   widget->style = gtk_style_attach (widget->style, widget->window);
4482 }
4483
4484 /*****************************************
4485  * gtk_widget_real_unrealize:
4486  *
4487  *   arguments:
4488  *
4489  *   results:
4490  *****************************************/
4491
4492 static void
4493 gtk_widget_real_unrealize (GtkWidget *widget)
4494 {
4495   g_return_if_fail (widget != NULL);
4496   g_return_if_fail (GTK_IS_WIDGET (widget));
4497
4498   if (GTK_WIDGET_MAPPED (widget))
4499     gtk_widget_real_unmap (widget);
4500
4501   GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4502
4503   /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT (widget)->klass->type));
4504    */
4505
4506    /* We must do unrealize child widget BEFORE container widget.
4507     * gdk_window_destroy() destroys specified xwindow and its sub-xwindows.
4508     * So, unrealizing container widget bofore its children causes the problem 
4509     * (for example, gdk_ic_destroy () with destroyed window causes crash. )
4510     */
4511
4512   if (GTK_IS_CONTAINER (widget))
4513     gtk_container_forall (GTK_CONTAINER (widget),
4514                           (GtkCallback) gtk_widget_unrealize,
4515                           NULL);
4516
4517   gtk_style_detach (widget->style);
4518   if (!GTK_WIDGET_NO_WINDOW (widget))
4519     {
4520       gdk_window_set_user_data (widget->window, NULL);
4521       gdk_window_destroy (widget->window);
4522       widget->window = NULL;
4523     }
4524   else
4525     {
4526       gdk_window_unref (widget->window);
4527       widget->window = NULL;
4528     }
4529
4530   GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
4531 }
4532
4533 static void
4534 gtk_widget_real_draw (GtkWidget    *widget,
4535                       GdkRectangle *area)
4536 {
4537   GdkEventExpose event;
4538   
4539   g_return_if_fail (widget != NULL);
4540   g_return_if_fail (GTK_IS_WIDGET (widget));
4541   g_return_if_fail (area != NULL);
4542   
4543   if (GTK_WIDGET_DRAWABLE (widget))
4544     {
4545       event.type = GDK_EXPOSE;
4546       event.send_event = TRUE;
4547       event.window = widget->window;
4548       event.area = *area;
4549       event.count = 0;
4550       
4551       gdk_window_ref (event.window);
4552       gtk_widget_event (widget, (GdkEvent*) &event);
4553       gdk_window_unref (event.window);
4554     }
4555 }
4556
4557 static void
4558 gtk_widget_real_size_request (GtkWidget         *widget,
4559                               GtkRequisition    *requisition)
4560 {
4561   g_return_if_fail (widget != NULL);
4562   g_return_if_fail (GTK_IS_WIDGET (widget));
4563
4564   requisition->width = widget->requisition.width;
4565   requisition->height = widget->requisition.height;
4566 }
4567
4568 /*****************************************
4569  * gtk_widget_peek_colormap:
4570  *
4571  *   arguments:
4572  *
4573  *   results:
4574  *****************************************/
4575
4576 static GdkColormap*
4577 gtk_widget_peek_colormap (void)
4578 {
4579   if (colormap_stack)
4580     return (GdkColormap*) colormap_stack->data;
4581   return gtk_widget_get_default_colormap ();
4582 }
4583
4584 static void
4585 gtk_widget_propagate_state (GtkWidget           *widget,
4586                             GtkStateData        *data)
4587 {
4588   guint8 old_state;
4589
4590   /* don't call this function with state==GTK_STATE_INSENSITIVE,
4591    * parent_sensitive==TRUE on a sensitive widget
4592    */
4593
4594   old_state = GTK_WIDGET_STATE (widget);
4595
4596   if (data->parent_sensitive)
4597     {
4598       GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4599
4600       if (GTK_WIDGET_IS_SENSITIVE (widget))
4601         {
4602           if (data->state_restoration)
4603             GTK_WIDGET_STATE (widget) = GTK_WIDGET_SAVED_STATE (widget);
4604           else
4605             GTK_WIDGET_STATE (widget) = data->state;
4606         }
4607       else
4608         {
4609           GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4610           if (!data->state_restoration &&
4611               data->state != GTK_STATE_INSENSITIVE)
4612             GTK_WIDGET_SAVED_STATE (widget) = data->state;
4613         }
4614     }
4615   else
4616     {
4617       GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4618       if (!data->state_restoration)
4619         {
4620           if (data->state != GTK_STATE_INSENSITIVE)
4621             GTK_WIDGET_SAVED_STATE (widget) = data->state;
4622         }
4623       else if (GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE)
4624         GTK_WIDGET_SAVED_STATE (widget) = GTK_WIDGET_STATE (widget);
4625       GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4626     }
4627
4628   if (GTK_WIDGET_HAS_FOCUS (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
4629     {
4630       GtkWidget *window;
4631
4632       window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
4633       if (window)
4634         gtk_window_set_focus (GTK_WINDOW (window), NULL);
4635     }
4636
4637   if (old_state != GTK_WIDGET_STATE (widget))
4638     {
4639       gtk_widget_ref (widget);
4640       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state);
4641       
4642       if (GTK_IS_CONTAINER (widget))
4643         {
4644           data->parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget) != FALSE);
4645           data->state = GTK_WIDGET_STATE (widget);
4646           if (data->use_forall)
4647             gtk_container_forall (GTK_CONTAINER (widget),
4648                                   (GtkCallback) gtk_widget_propagate_state,
4649                                   data);
4650           else
4651             gtk_container_foreach (GTK_CONTAINER (widget),
4652                                    (GtkCallback) gtk_widget_propagate_state,
4653                                    data);
4654         }
4655       gtk_widget_unref (widget);
4656     }
4657 }
4658
4659 /*****************************************
4660  * gtk_widget_aux_info_new:
4661  *
4662  *   arguments:
4663  *
4664  *   results:
4665  *****************************************/
4666
4667 static GtkWidgetAuxInfo*
4668 gtk_widget_aux_info_new (void)
4669 {
4670   GtkWidgetAuxInfo *aux_info;
4671   
4672   if (!aux_info_mem_chunk)
4673     aux_info_mem_chunk = g_mem_chunk_new ("widget aux info mem chunk",
4674                                           sizeof (GtkWidgetAuxInfo),
4675                                           1024, G_ALLOC_AND_FREE);
4676   
4677   aux_info = g_chunk_new (GtkWidgetAuxInfo, aux_info_mem_chunk);
4678   
4679   aux_info->x = -1;
4680   aux_info->y = -1;
4681   aux_info->width = 0;
4682   aux_info->height = 0;
4683   
4684   return aux_info;
4685 }
4686
4687 /*****************************************
4688  * gtk_widget_aux_info_destroy:
4689  *
4690  *   arguments:
4691  *
4692  *   results:
4693  *****************************************/
4694
4695 static void
4696 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
4697 {
4698   g_return_if_fail (aux_info != NULL);
4699   
4700   g_mem_chunk_free (aux_info_mem_chunk, aux_info);
4701 }
4702
4703 static void
4704 gtk_widget_shape_info_destroy (GtkWidgetShapeInfo *info)
4705 {
4706   gdk_drawable_unref (info->shape_mask);
4707   g_free (info);
4708 }
4709
4710 /*****************************************
4711  * gtk_widget_shape_combine_mask: 
4712  *   set a shape for this widgets' gdk window, this allows for
4713  *   transparent windows etc., see gdk_window_shape_combine_mask
4714  *   for more information
4715  *
4716  *   arguments:
4717  *
4718  *   results:
4719  *****************************************/
4720 void
4721 gtk_widget_shape_combine_mask (GtkWidget *widget,
4722                                GdkBitmap *shape_mask,
4723                                gint       offset_x,
4724                                gint       offset_y)
4725 {
4726   GtkWidgetShapeInfo* shape_info;
4727   
4728   g_return_if_fail (widget != NULL);
4729   g_return_if_fail (GTK_IS_WIDGET (widget));
4730   /*  set_shape doesn't work on widgets without gdk window */
4731   g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
4732
4733   if (!shape_mask)
4734     {
4735       GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4736       
4737       if (widget->window)
4738         gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
4739       
4740       gtk_object_remove_data (GTK_OBJECT (widget), shape_info_key);
4741     }
4742   else
4743     {
4744       GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4745       
4746       shape_info = g_new (GtkWidgetShapeInfo, 1);
4747       gtk_object_set_data_full (GTK_OBJECT (widget), shape_info_key, shape_info,
4748                                 (GDestroyNotify)gtk_widget_shape_info_destroy);
4749       
4750       shape_info->shape_mask = gdk_drawable_ref (shape_mask);
4751       shape_info->offset_x = offset_x;
4752       shape_info->offset_y = offset_y;
4753       
4754       /* set shape if widget has a gdk window allready.
4755        * otherwise the shape is scheduled to be set by gtk_widget_realize.
4756        */
4757       if (widget->window)
4758         gdk_window_shape_combine_mask (widget->window, shape_mask,
4759                                        offset_x, offset_y);
4760     }
4761 }
4762
4763 static void
4764 gtk_reset_shapes_recurse (GtkWidget *widget,
4765                           GdkWindow *window)
4766 {
4767   gpointer data;
4768   GList *list;
4769
4770   gdk_window_get_user_data (window, &data);
4771   if (data != widget)
4772     return;
4773
4774   gdk_window_shape_combine_mask (window, NULL, 0, 0);
4775   for (list = gdk_window_peek_children (window); list; list = list->next)
4776     gtk_reset_shapes_recurse (widget, list->data);
4777 }
4778
4779 void
4780 gtk_widget_reset_shapes (GtkWidget *widget)
4781 {
4782   g_return_if_fail (widget != NULL);
4783   g_return_if_fail (GTK_IS_WIDGET (widget));
4784   g_return_if_fail (GTK_WIDGET_REALIZED (widget));
4785
4786   if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
4787     gtk_reset_shapes_recurse (widget, widget->window);
4788 }
4789
4790 GtkWidget*
4791 gtk_widget_ref (GtkWidget *widget)
4792 {
4793   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4794
4795   return (GtkWidget*) g_object_ref ((GObject*) widget);
4796 }
4797
4798 void
4799 gtk_widget_unref (GtkWidget *widget)
4800 {
4801   g_return_if_fail (GTK_IS_WIDGET (widget));
4802
4803   g_object_unref ((GObject*) widget);
4804 }
4805
4806 void
4807 gtk_widget_path (GtkWidget *widget,
4808                  guint     *path_length_p,
4809                  gchar    **path_p,
4810                  gchar    **path_reversed_p)
4811 {
4812   static gchar *rev_path = NULL;
4813   static guint  path_len = 0;
4814   guint len;
4815   
4816   g_return_if_fail (widget != NULL);
4817   g_return_if_fail (GTK_IS_WIDGET (widget));
4818   
4819   len = 0;
4820   do
4821     {
4822       gchar *string;
4823       gchar *d, *s;
4824       guint l;
4825       
4826       string = gtk_widget_get_name (widget);
4827       l = strlen (string);
4828       while (path_len <= len + l + 1)
4829         {
4830           path_len += INIT_PATH_SIZE;
4831           rev_path = g_realloc (rev_path, path_len);
4832         }
4833       s = string + l - 1;
4834       d = rev_path + len;
4835       while (s >= string)
4836         *(d++) = *(s--);
4837       len += l;
4838       
4839       widget = widget->parent;
4840       
4841       if (widget)
4842         rev_path[len++] = '.';
4843       else
4844         rev_path[len++] = 0;
4845     }
4846   while (widget);
4847   
4848   if (path_length_p)
4849     *path_length_p = len - 1;
4850   if (path_reversed_p)
4851     *path_reversed_p = g_strdup (rev_path);
4852   if (path_p)
4853     {
4854       *path_p = g_strdup (rev_path);
4855       g_strreverse (*path_p);
4856     }
4857 }
4858
4859 void
4860 gtk_widget_class_path (GtkWidget *widget,
4861                        guint     *path_length_p,
4862                        gchar    **path_p,
4863                        gchar    **path_reversed_p)
4864 {
4865   static gchar *rev_path = NULL;
4866   static guint  path_len = 0;
4867   guint len;
4868   
4869   g_return_if_fail (widget != NULL);
4870   g_return_if_fail (GTK_IS_WIDGET (widget));
4871   
4872   len = 0;
4873   do
4874     {
4875       gchar *string;
4876       gchar *d, *s;
4877       guint l;
4878       
4879       string = gtk_type_name (GTK_WIDGET_TYPE (widget));
4880       l = strlen (string);
4881       while (path_len <= len + l + 1)
4882         {
4883           path_len += INIT_PATH_SIZE;
4884           rev_path = g_realloc (rev_path, path_len);
4885         }
4886       s = string + l - 1;
4887       d = rev_path + len;
4888       while (s >= string)
4889         *(d++) = *(s--);
4890       len += l;
4891       
4892       widget = widget->parent;
4893       
4894       if (widget)
4895         rev_path[len++] = '.';
4896       else
4897         rev_path[len++] = 0;
4898     }
4899   while (widget);
4900   
4901   if (path_length_p)
4902     *path_length_p = len - 1;
4903   if (path_reversed_p)
4904     *path_reversed_p = g_strdup (rev_path);
4905   if (path_p)
4906     {
4907       *path_p = g_strdup (rev_path);
4908       g_strreverse (*path_p);
4909     }
4910 }