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