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