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