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