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