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