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