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