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