source: trunk/third/gtk/gtk/gtkwidget.c @ 15781

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