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