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