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