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