1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
21 #include "gtkcontainer.h"
24 #include "gtkselection.h"
25 #include "gtksignal.h"
26 #include "gtkwidget.h"
27 #include "gtkwindow.h"
28 #include "gtkbindings.h"
29 #include "gtkprivate.h"
34 #define WIDGET_CLASS(w) GTK_WIDGET_CLASS (GTK_OBJECT (w)->klass)
35 #define INIT_PATH_SIZE (512)
72 PROPERTY_NOTIFY_EVENT,
73 SELECTION_CLEAR_EVENT,
74 SELECTION_REQUEST_EVENT,
75 SELECTION_NOTIFY_EVENT,
90 VISIBILITY_NOTIFY_EVENT,
115 typedef struct _GtkStateData GtkStateData;
120 guint state_restoration : 1;
121 guint parent_sensitive : 1;
122 guint use_forall : 1;
125 static void gtk_widget_class_init (GtkWidgetClass *klass);
126 static void gtk_widget_init (GtkWidget *widget);
127 static void gtk_widget_set_arg (GtkObject *object,
130 static void gtk_widget_get_arg (GtkObject *object,
133 static void gtk_widget_shutdown (GtkObject *object);
134 static void gtk_widget_real_destroy (GtkObject *object);
135 static void gtk_widget_finalize (GtkObject *object);
136 static void gtk_widget_real_show (GtkWidget *widget);
137 static void gtk_widget_real_hide (GtkWidget *widget);
138 static void gtk_widget_real_map (GtkWidget *widget);
139 static void gtk_widget_real_unmap (GtkWidget *widget);
140 static void gtk_widget_real_realize (GtkWidget *widget);
141 static void gtk_widget_real_unrealize (GtkWidget *widget);
142 static void gtk_widget_real_draw (GtkWidget *widget,
144 static void gtk_widget_real_size_request (GtkWidget *widget,
145 GtkRequisition *requisition);
146 static void gtk_widget_real_size_allocate (GtkWidget *widget,
147 GtkAllocation *allocation);
148 static gint gtk_widget_real_key_press_event (GtkWidget *widget,
150 static gint gtk_widget_real_key_release_event (GtkWidget *widget,
152 static void gtk_widget_style_set (GtkWidget *widget,
153 GtkStyle *previous_style);
154 static void gtk_widget_real_grab_focus (GtkWidget *focus_widget);
156 static void gtk_widget_redraw_queue_remove (GtkWidget *widget);
159 static GdkColormap* gtk_widget_peek_colormap (void);
160 static GdkVisual* gtk_widget_peek_visual (void);
161 static GtkStyle* gtk_widget_peek_style (void);
163 static void gtk_widget_reparent_container_child (GtkWidget *widget,
164 gpointer client_data);
165 static void gtk_widget_propagate_state (GtkWidget *widget,
167 static void gtk_widget_set_style_internal (GtkWidget *widget,
169 gboolean initial_emission);
170 static void gtk_widget_set_style_recurse (GtkWidget *widget,
171 gpointer client_data);
173 static GtkWidgetAuxInfo* gtk_widget_aux_info_new (void);
174 static void gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
176 static GtkObjectClass *parent_class = NULL;
177 static guint widget_signals[LAST_SIGNAL] = { 0 };
179 static GMemChunk *aux_info_mem_chunk = NULL;
181 static GdkColormap *default_colormap = NULL;
182 static GdkVisual *default_visual = NULL;
183 static GtkStyle *gtk_default_style = NULL;
185 static GSList *colormap_stack = NULL;
186 static GSList *visual_stack = NULL;
187 static GSList *style_stack = NULL;
188 static guint composite_child_stack = 0;
189 static GSList *gtk_widget_redraw_queue = NULL;
191 static const gchar *aux_info_key = "gtk-aux-info";
192 static guint aux_info_key_id = 0;
193 static const gchar *event_key = "gtk-event-mask";
194 static guint event_key_id = 0;
195 static const gchar *extension_event_key = "gtk-extension-event-mode";
196 static guint extension_event_key_id = 0;
197 static const gchar *parent_window_key = "gtk-parent-window";
198 static guint parent_window_key_id = 0;
199 static const gchar *saved_default_style_key = "gtk-saved-default-style";
200 static guint saved_default_style_key_id = 0;
201 static const gchar *shape_info_key = "gtk-shape-info";
202 static const gchar *colormap_key = "gtk-colormap";
203 static const gchar *visual_key = "gtk-visual";
205 static const gchar *rc_style_key = "gtk-rc-style";
206 static guint rc_style_key_id = 0;
208 /*****************************************
209 * gtk_widget_get_type:
214 *****************************************/
217 gtk_widget_get_type (void)
219 static GtkType widget_type = 0;
223 static const GtkTypeInfo widget_info =
227 sizeof (GtkWidgetClass),
228 (GtkClassInitFunc) gtk_widget_class_init,
229 (GtkObjectInitFunc) gtk_widget_init,
230 /* reserved_1 */ NULL,
231 /* reserved_2 */ NULL,
232 (GtkClassInitFunc) NULL,
235 widget_type = gtk_type_unique (gtk_object_get_type (), &widget_info);
241 /*****************************************
242 * gtk_widget_class_init:
247 *****************************************/
250 gtk_widget_debug_msg (GtkWidget *widget,
253 fprintf (stderr, "Gtk-DEBUG: %s\n", string);
257 gtk_widget_class_init (GtkWidgetClass *klass)
259 GtkObjectClass *object_class;
261 object_class = (GtkObjectClass*) klass;
263 parent_class = gtk_type_class (gtk_object_get_type ());
265 gtk_object_add_arg_type ("GtkWidget::name", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NAME);
266 gtk_object_add_arg_type ("GtkWidget::parent", GTK_TYPE_CONTAINER, GTK_ARG_READWRITE, ARG_PARENT);
267 gtk_object_add_arg_type ("GtkWidget::x", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_X);
268 gtk_object_add_arg_type ("GtkWidget::y", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_Y);
269 gtk_object_add_arg_type ("GtkWidget::width", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_WIDTH);
270 gtk_object_add_arg_type ("GtkWidget::height", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_HEIGHT);
271 gtk_object_add_arg_type ("GtkWidget::visible", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_VISIBLE);
272 gtk_object_add_arg_type ("GtkWidget::sensitive", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SENSITIVE);
273 gtk_object_add_arg_type ("GtkWidget::can_focus", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_CAN_FOCUS);
274 gtk_object_add_arg_type ("GtkWidget::has_focus", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HAS_FOCUS);
275 gtk_object_add_arg_type ("GtkWidget::can_default", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_CAN_DEFAULT);
276 gtk_object_add_arg_type ("GtkWidget::has_default", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HAS_DEFAULT);
277 gtk_object_add_arg_type ("GtkWidget::composite_child", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_COMPOSITE_CHILD);
278 gtk_object_add_arg_type ("GtkWidget::style", GTK_TYPE_STYLE, GTK_ARG_READWRITE, ARG_STYLE);
279 gtk_object_add_arg_type ("GtkWidget::events", GTK_TYPE_GDK_EVENT_MASK, GTK_ARG_READWRITE, ARG_EVENTS);
280 gtk_object_add_arg_type ("GtkWidget::extension_events", GTK_TYPE_GDK_EVENT_MASK, GTK_ARG_READWRITE, ARG_EXTENSION_EVENTS);
282 widget_signals[SHOW] =
283 gtk_signal_new ("show",
286 GTK_SIGNAL_OFFSET (GtkWidgetClass, show),
287 gtk_marshal_NONE__NONE,
289 widget_signals[HIDE] =
290 gtk_signal_new ("hide",
293 GTK_SIGNAL_OFFSET (GtkWidgetClass, hide),
294 gtk_marshal_NONE__NONE,
296 widget_signals[MAP] =
297 gtk_signal_new ("map",
300 GTK_SIGNAL_OFFSET (GtkWidgetClass, map),
301 gtk_marshal_NONE__NONE,
303 widget_signals[UNMAP] =
304 gtk_signal_new ("unmap",
307 GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap),
308 gtk_marshal_NONE__NONE,
310 widget_signals[REALIZE] =
311 gtk_signal_new ("realize",
314 GTK_SIGNAL_OFFSET (GtkWidgetClass, realize),
315 gtk_marshal_NONE__NONE,
317 widget_signals[UNREALIZE] =
318 gtk_signal_new ("unrealize",
321 GTK_SIGNAL_OFFSET (GtkWidgetClass, unrealize),
322 gtk_marshal_NONE__NONE,
324 widget_signals[DRAW] =
325 gtk_signal_new ("draw",
328 GTK_SIGNAL_OFFSET (GtkWidgetClass, draw),
329 gtk_marshal_NONE__POINTER,
332 widget_signals[DRAW_FOCUS] =
333 gtk_signal_new ("draw_focus",
336 GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_focus),
337 gtk_marshal_NONE__NONE,
339 widget_signals[DRAW_DEFAULT] =
340 gtk_signal_new ("draw_default",
343 GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_default),
344 gtk_marshal_NONE__NONE,
346 widget_signals[SIZE_REQUEST] =
347 gtk_signal_new ("size_request",
350 GTK_SIGNAL_OFFSET (GtkWidgetClass, size_request),
351 gtk_marshal_NONE__POINTER,
354 widget_signals[SIZE_ALLOCATE] =
355 gtk_signal_new ("size_allocate",
358 GTK_SIGNAL_OFFSET (GtkWidgetClass, size_allocate),
359 gtk_marshal_NONE__POINTER,
362 widget_signals[STATE_CHANGED] =
363 gtk_signal_new ("state_changed",
366 GTK_SIGNAL_OFFSET (GtkWidgetClass, state_changed),
367 gtk_marshal_NONE__UINT,
369 GTK_TYPE_STATE_TYPE);
370 widget_signals[PARENT_SET] =
371 gtk_signal_new ("parent_set",
374 GTK_SIGNAL_OFFSET (GtkWidgetClass, parent_set),
375 gtk_marshal_NONE__OBJECT,
378 widget_signals[STYLE_SET] =
379 gtk_signal_new ("style_set",
382 GTK_SIGNAL_OFFSET (GtkWidgetClass, style_set),
383 gtk_marshal_NONE__POINTER,
386 widget_signals[ADD_ACCELERATOR] =
387 gtk_accel_group_create_add (object_class->type, GTK_RUN_LAST,
388 GTK_SIGNAL_OFFSET (GtkWidgetClass, add_accelerator));
389 widget_signals[REMOVE_ACCELERATOR] =
390 gtk_accel_group_create_remove (object_class->type, GTK_RUN_LAST,
391 GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator));
392 widget_signals[GRAB_FOCUS] =
393 gtk_signal_new ("grab_focus",
394 GTK_RUN_LAST | GTK_RUN_ACTION,
396 GTK_SIGNAL_OFFSET (GtkWidgetClass, grab_focus),
397 gtk_marshal_NONE__NONE,
399 widget_signals[EVENT] =
400 gtk_signal_new ("event",
403 GTK_SIGNAL_OFFSET (GtkWidgetClass, event),
404 gtk_marshal_BOOL__POINTER,
407 widget_signals[BUTTON_PRESS_EVENT] =
408 gtk_signal_new ("button_press_event",
411 GTK_SIGNAL_OFFSET (GtkWidgetClass, button_press_event),
412 gtk_marshal_BOOL__POINTER,
415 widget_signals[BUTTON_RELEASE_EVENT] =
416 gtk_signal_new ("button_release_event",
419 GTK_SIGNAL_OFFSET (GtkWidgetClass, button_release_event),
420 gtk_marshal_BOOL__POINTER,
423 widget_signals[MOTION_NOTIFY_EVENT] =
424 gtk_signal_new ("motion_notify_event",
427 GTK_SIGNAL_OFFSET (GtkWidgetClass, motion_notify_event),
428 gtk_marshal_BOOL__POINTER,
431 widget_signals[DELETE_EVENT] =
432 gtk_signal_new ("delete_event",
435 GTK_SIGNAL_OFFSET (GtkWidgetClass, delete_event),
436 gtk_marshal_BOOL__POINTER,
439 widget_signals[DESTROY_EVENT] =
440 gtk_signal_new ("destroy_event",
443 GTK_SIGNAL_OFFSET (GtkWidgetClass, destroy_event),
444 gtk_marshal_BOOL__POINTER,
447 widget_signals[EXPOSE_EVENT] =
448 gtk_signal_new ("expose_event",
451 GTK_SIGNAL_OFFSET (GtkWidgetClass, expose_event),
452 gtk_marshal_BOOL__POINTER,
455 widget_signals[KEY_PRESS_EVENT] =
456 gtk_signal_new ("key_press_event",
459 GTK_SIGNAL_OFFSET (GtkWidgetClass, key_press_event),
460 gtk_marshal_BOOL__POINTER,
463 widget_signals[KEY_RELEASE_EVENT] =
464 gtk_signal_new ("key_release_event",
467 GTK_SIGNAL_OFFSET (GtkWidgetClass, key_release_event),
468 gtk_marshal_BOOL__POINTER,
471 widget_signals[ENTER_NOTIFY_EVENT] =
472 gtk_signal_new ("enter_notify_event",
475 GTK_SIGNAL_OFFSET (GtkWidgetClass, enter_notify_event),
476 gtk_marshal_BOOL__POINTER,
479 widget_signals[LEAVE_NOTIFY_EVENT] =
480 gtk_signal_new ("leave_notify_event",
483 GTK_SIGNAL_OFFSET (GtkWidgetClass, leave_notify_event),
484 gtk_marshal_BOOL__POINTER,
487 widget_signals[CONFIGURE_EVENT] =
488 gtk_signal_new ("configure_event",
491 GTK_SIGNAL_OFFSET (GtkWidgetClass, configure_event),
492 gtk_marshal_BOOL__POINTER,
495 widget_signals[FOCUS_IN_EVENT] =
496 gtk_signal_new ("focus_in_event",
499 GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_in_event),
500 gtk_marshal_BOOL__POINTER,
503 widget_signals[FOCUS_OUT_EVENT] =
504 gtk_signal_new ("focus_out_event",
507 GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_out_event),
508 gtk_marshal_BOOL__POINTER,
511 widget_signals[MAP_EVENT] =
512 gtk_signal_new ("map_event",
515 GTK_SIGNAL_OFFSET (GtkWidgetClass, map_event),
516 gtk_marshal_BOOL__POINTER,
519 widget_signals[UNMAP_EVENT] =
520 gtk_signal_new ("unmap_event",
523 GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap_event),
524 gtk_marshal_BOOL__POINTER,
527 widget_signals[PROPERTY_NOTIFY_EVENT] =
528 gtk_signal_new ("property_notify_event",
531 GTK_SIGNAL_OFFSET (GtkWidgetClass, property_notify_event),
532 gtk_marshal_BOOL__POINTER,
535 widget_signals[SELECTION_CLEAR_EVENT] =
536 gtk_signal_new ("selection_clear_event",
539 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_clear_event),
540 gtk_marshal_BOOL__POINTER,
543 widget_signals[SELECTION_REQUEST_EVENT] =
544 gtk_signal_new ("selection_request_event",
547 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_request_event),
548 gtk_marshal_BOOL__POINTER,
551 widget_signals[SELECTION_NOTIFY_EVENT] =
552 gtk_signal_new ("selection_notify_event",
555 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_notify_event),
556 gtk_marshal_BOOL__POINTER,
559 widget_signals[SELECTION_RECEIVED] =
560 gtk_signal_new ("selection_received",
563 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_received),
564 gtk_marshal_NONE__POINTER_UINT,
566 GTK_TYPE_SELECTION_DATA,
568 widget_signals[SELECTION_GET] =
569 gtk_signal_new ("selection_get",
572 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_get),
573 gtk_marshal_NONE__POINTER_UINT_UINT,
575 GTK_TYPE_SELECTION_DATA,
578 widget_signals[PROXIMITY_IN_EVENT] =
579 gtk_signal_new ("proximity_in_event",
582 GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_in_event),
583 gtk_marshal_BOOL__POINTER,
586 widget_signals[PROXIMITY_OUT_EVENT] =
587 gtk_signal_new ("proximity_out_event",
590 GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_out_event),
591 gtk_marshal_BOOL__POINTER,
594 widget_signals[DRAG_LEAVE] =
595 gtk_signal_new ("drag_leave",
598 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_leave),
599 gtk_marshal_NONE__POINTER_UINT,
601 GTK_TYPE_GDK_DRAG_CONTEXT,
603 widget_signals[DRAG_BEGIN] =
604 gtk_signal_new ("drag_begin",
607 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin),
608 gtk_marshal_NONE__POINTER,
610 GTK_TYPE_GDK_DRAG_CONTEXT);
611 widget_signals[DRAG_END] =
612 gtk_signal_new ("drag_end",
615 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end),
616 gtk_marshal_NONE__POINTER,
618 GTK_TYPE_GDK_DRAG_CONTEXT);
619 widget_signals[DRAG_DATA_DELETE] =
620 gtk_signal_new ("drag_data_delete",
623 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_delete),
624 gtk_marshal_NONE__POINTER,
626 GTK_TYPE_GDK_DRAG_CONTEXT);
627 widget_signals[DRAG_MOTION] =
628 gtk_signal_new ("drag_motion",
631 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_motion),
632 gtk_marshal_BOOL__POINTER_INT_INT_UINT,
634 GTK_TYPE_GDK_DRAG_CONTEXT,
638 widget_signals[DRAG_DROP] =
639 gtk_signal_new ("drag_drop",
642 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_drop),
643 gtk_marshal_BOOL__POINTER_INT_INT_UINT,
645 GTK_TYPE_GDK_DRAG_CONTEXT,
649 widget_signals[DRAG_DATA_GET] =
650 gtk_signal_new ("drag_data_get",
653 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_get),
654 gtk_marshal_NONE__POINTER_POINTER_UINT_UINT,
656 GTK_TYPE_GDK_DRAG_CONTEXT,
657 GTK_TYPE_SELECTION_DATA,
660 widget_signals[DRAG_DATA_RECEIVED] =
661 gtk_signal_new ("drag_data_received",
664 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_received),
665 gtk_marshal_NONE__POINTER_INT_INT_POINTER_UINT_UINT,
667 GTK_TYPE_GDK_DRAG_CONTEXT,
670 GTK_TYPE_SELECTION_DATA,
673 widget_signals[VISIBILITY_NOTIFY_EVENT] =
674 gtk_signal_new ("visibility_notify_event",
677 GTK_SIGNAL_OFFSET (GtkWidgetClass, visibility_notify_event),
678 gtk_marshal_BOOL__POINTER,
681 widget_signals[CLIENT_EVENT] =
682 gtk_signal_new ("client_event",
685 GTK_SIGNAL_OFFSET (GtkWidgetClass, client_event),
686 gtk_marshal_BOOL__POINTER,
689 widget_signals[NO_EXPOSE_EVENT] =
690 gtk_signal_new ("no_expose_event",
693 GTK_SIGNAL_OFFSET (GtkWidgetClass, no_expose_event),
694 gtk_marshal_BOOL__POINTER,
697 widget_signals[DEBUG_MSG] =
698 gtk_signal_new ("debug_msg",
699 GTK_RUN_LAST | GTK_RUN_ACTION,
701 GTK_SIGNAL_OFFSET (GtkWidgetClass, debug_msg),
702 gtk_marshal_NONE__STRING,
706 gtk_object_class_add_signals (object_class, widget_signals, LAST_SIGNAL);
708 object_class->set_arg = gtk_widget_set_arg;
709 object_class->get_arg = gtk_widget_get_arg;
710 object_class->shutdown = gtk_widget_shutdown;
711 object_class->destroy = gtk_widget_real_destroy;
712 object_class->finalize = gtk_widget_finalize;
714 klass->activate_signal = 0;
715 klass->set_scroll_adjustments_signal = 0;
716 klass->show = gtk_widget_real_show;
717 klass->show_all = gtk_widget_show;
718 klass->hide = gtk_widget_real_hide;
719 klass->hide_all = gtk_widget_hide;
720 klass->map = gtk_widget_real_map;
721 klass->unmap = gtk_widget_real_unmap;
722 klass->realize = gtk_widget_real_realize;
723 klass->unrealize = gtk_widget_real_unrealize;
724 klass->draw = gtk_widget_real_draw;
725 klass->draw_focus = NULL;
726 klass->size_request = gtk_widget_real_size_request;
727 klass->size_allocate = gtk_widget_real_size_allocate;
728 klass->state_changed = NULL;
729 klass->parent_set = NULL;
730 klass->style_set = gtk_widget_style_set;
731 klass->add_accelerator = (void*) gtk_accel_group_handle_add;
732 klass->remove_accelerator = (void*) gtk_accel_group_handle_remove;
733 klass->grab_focus = gtk_widget_real_grab_focus;
735 klass->button_press_event = NULL;
736 klass->button_release_event = NULL;
737 klass->motion_notify_event = NULL;
738 klass->delete_event = NULL;
739 klass->destroy_event = NULL;
740 klass->expose_event = NULL;
741 klass->key_press_event = gtk_widget_real_key_press_event;
742 klass->key_release_event = gtk_widget_real_key_release_event;
743 klass->enter_notify_event = NULL;
744 klass->leave_notify_event = NULL;
745 klass->configure_event = NULL;
746 klass->focus_in_event = NULL;
747 klass->focus_out_event = NULL;
748 klass->map_event = NULL;
749 klass->unmap_event = NULL;
750 klass->property_notify_event = gtk_selection_property_notify;
751 klass->selection_clear_event = gtk_selection_clear;
752 klass->selection_request_event = gtk_selection_request;
753 klass->selection_notify_event = gtk_selection_notify;
754 klass->selection_received = NULL;
755 klass->proximity_in_event = NULL;
756 klass->proximity_out_event = NULL;
757 klass->drag_begin = NULL;
758 klass->drag_end = NULL;
759 klass->drag_data_delete = NULL;
760 klass->drag_leave = NULL;
761 klass->drag_motion = NULL;
762 klass->drag_drop = NULL;
763 klass->drag_data_received = NULL;
765 klass->no_expose_event = NULL;
767 klass->debug_msg = gtk_widget_debug_msg;
771 gtk_widget_set_arg (GtkObject *object,
777 widget = GTK_WIDGET (object);
784 gtk_widget_set_name (widget, GTK_VALUE_STRING (*arg));
787 gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT (*arg)), widget);
790 gtk_widget_set_uposition (widget, GTK_VALUE_INT (*arg), -2);
793 gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT (*arg));
796 gtk_widget_set_usize (widget, GTK_VALUE_INT (*arg), -2);
799 gtk_widget_set_usize (widget, -2, GTK_VALUE_INT (*arg));
802 if (GTK_VALUE_BOOL(*arg))
803 gtk_widget_show (widget);
805 gtk_widget_hide (widget);
808 gtk_widget_set_sensitive (widget, GTK_VALUE_BOOL (*arg));
811 saved_flags = GTK_WIDGET_FLAGS (widget);
812 if (GTK_VALUE_BOOL (*arg))
813 GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
815 GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
816 if (saved_flags != GTK_WIDGET_FLAGS (widget))
817 gtk_widget_queue_resize (widget);
820 if (GTK_VALUE_BOOL (*arg))
821 gtk_widget_grab_focus (widget);
823 case ARG_CAN_DEFAULT:
824 saved_flags = GTK_WIDGET_FLAGS (widget);
825 if (GTK_VALUE_BOOL (*arg))
826 GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
828 GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
829 if (saved_flags != GTK_WIDGET_FLAGS (widget))
830 gtk_widget_queue_resize (widget);
832 case ARG_HAS_DEFAULT:
833 if (GTK_VALUE_BOOL (*arg))
834 gtk_widget_grab_default (widget);
836 case ARG_COMPOSITE_CHILD:
837 if (GTK_VALUE_BOOL(*arg))
838 GTK_WIDGET_SET_FLAGS (widget, GTK_COMPOSITE_CHILD);
840 GTK_WIDGET_UNSET_FLAGS (widget, GTK_COMPOSITE_CHILD);
843 gtk_widget_set_style (widget, (GtkStyle*) GTK_VALUE_BOXED (*arg));
846 if (!GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget))
847 gtk_widget_set_events (widget, GTK_VALUE_FLAGS (*arg));
849 case ARG_EXTENSION_EVENTS:
850 gtk_widget_set_extension_events (widget, GTK_VALUE_FLAGS (*arg));
857 /*****************************************
858 * gtk_widget_get_arg:
863 *****************************************/
866 gtk_widget_get_arg (GtkObject *object,
872 widget = GTK_WIDGET (object);
876 GtkWidgetAuxInfo *aux_info;
878 GdkExtensionMode *modep;
882 GTK_VALUE_STRING (*arg) = g_strdup (widget->name);
884 GTK_VALUE_STRING (*arg) = g_strdup ("");
887 GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
890 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
892 GTK_VALUE_INT (*arg) = -1;
894 GTK_VALUE_INT (*arg) = aux_info->x;
897 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
899 GTK_VALUE_INT (*arg) = -1;
901 GTK_VALUE_INT (*arg) = aux_info->y;
904 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
906 GTK_VALUE_INT (*arg) = -1;
908 GTK_VALUE_INT (*arg) = aux_info->width;
911 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
913 GTK_VALUE_INT (*arg) = -1;
915 GTK_VALUE_INT (*arg) = aux_info->height;
918 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_VISIBLE (widget) != FALSE);
921 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_SENSITIVE (widget) != FALSE);
924 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_FOCUS (widget) != FALSE);
927 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_FOCUS (widget) != FALSE);
929 case ARG_CAN_DEFAULT:
930 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE);
932 case ARG_HAS_DEFAULT:
933 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_DEFAULT (widget) != FALSE);
935 case ARG_COMPOSITE_CHILD:
936 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_COMPOSITE_CHILD (widget) != FALSE);
939 GTK_VALUE_BOXED (*arg) = (gpointer) gtk_widget_get_style (widget);
942 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
944 GTK_VALUE_FLAGS (*arg) = 0;
946 GTK_VALUE_FLAGS (*arg) = *eventp;
948 case ARG_EXTENSION_EVENTS:
949 modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
951 GTK_VALUE_FLAGS (*arg) = 0;
953 GTK_VALUE_FLAGS (*arg) = *modep;
956 arg->type = GTK_TYPE_INVALID;
961 /*****************************************
967 *****************************************/
970 gtk_widget_init (GtkWidget *widget)
972 GdkColormap *colormap;
975 GTK_PRIVATE_FLAGS (widget) = 0;
976 widget->state = GTK_STATE_NORMAL;
977 widget->saved_state = GTK_STATE_NORMAL;
979 widget->requisition.width = 0;
980 widget->requisition.height = 0;
981 widget->allocation.x = -1;
982 widget->allocation.y = -1;
983 widget->allocation.width = 1;
984 widget->allocation.height = 1;
985 widget->window = NULL;
986 widget->parent = NULL;
988 GTK_WIDGET_SET_FLAGS (widget,
990 GTK_PARENT_SENSITIVE |
991 (composite_child_stack ? GTK_COMPOSITE_CHILD : 0));
993 widget->style = gtk_widget_peek_style ();
994 gtk_style_ref (widget->style);
996 colormap = gtk_widget_peek_colormap ();
997 visual = gtk_widget_peek_visual ();
999 /* XXX - should we ref the colormap and visual, too? */
1001 if (colormap != gtk_widget_get_default_colormap ())
1003 /* gdk_colormap_ref (colormap); */
1004 gtk_object_set_data (GTK_OBJECT (widget), colormap_key, colormap);
1007 if (visual != gtk_widget_get_default_visual ())
1009 /* gdk_visual_ref (visual); */
1010 gtk_object_set_data (GTK_OBJECT (widget), visual_key, visual);
1014 /*****************************************
1020 *****************************************/
1023 gtk_widget_new (GtkType widget_type,
1024 const gchar *first_arg_name,
1029 GSList *arg_list = NULL;
1030 GSList *info_list = NULL;
1033 g_return_val_if_fail (gtk_type_is_a (widget_type, GTK_TYPE_WIDGET), NULL);
1035 object = gtk_type_new (widget_type);
1037 va_start (var_args, first_arg_name);
1038 error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1047 g_warning ("gtk_widget_new(): %s", error);
1055 slist_arg = arg_list;
1056 slist_info = info_list;
1059 gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1060 slist_arg = slist_arg->next;
1061 slist_info = slist_info->next;
1063 gtk_args_collect_cleanup (arg_list, info_list);
1066 if (!GTK_OBJECT_CONSTRUCTED (object))
1067 gtk_object_default_construct (object);
1069 return GTK_WIDGET (object);
1072 /*****************************************
1078 *****************************************/
1081 gtk_widget_newv (GtkType type,
1085 g_return_val_if_fail (gtk_type_is_a (type, GTK_TYPE_WIDGET), NULL);
1087 return GTK_WIDGET (gtk_object_newv (type, nargs, args));
1090 /*****************************************
1096 *****************************************/
1099 gtk_widget_get (GtkWidget *widget,
1102 g_return_if_fail (widget != NULL);
1103 g_return_if_fail (GTK_IS_WIDGET (widget));
1104 g_return_if_fail (arg != NULL);
1106 gtk_object_getv (GTK_OBJECT (widget), 1, arg);
1109 /*****************************************
1115 *****************************************/
1118 gtk_widget_getv (GtkWidget *widget,
1122 g_return_if_fail (widget != NULL);
1123 g_return_if_fail (GTK_IS_WIDGET (widget));
1125 gtk_object_getv (GTK_OBJECT (widget), nargs, args);
1128 /*****************************************
1134 *****************************************/
1137 gtk_widget_set (GtkWidget *widget,
1138 const gchar *first_arg_name,
1143 GSList *arg_list = NULL;
1144 GSList *info_list = NULL;
1147 g_return_if_fail (widget != NULL);
1148 g_return_if_fail (GTK_IS_WIDGET (widget));
1150 object = GTK_OBJECT (widget);
1152 va_start (var_args, first_arg_name);
1153 error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1162 g_warning ("gtk_widget_set(): %s", error);
1170 slist_arg = arg_list;
1171 slist_info = info_list;
1174 gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1175 slist_arg = slist_arg->next;
1176 slist_info = slist_info->next;
1178 gtk_args_collect_cleanup (arg_list, info_list);
1182 /*****************************************
1188 *****************************************/
1191 gtk_widget_setv (GtkWidget *widget,
1195 g_return_if_fail (widget != NULL);
1196 g_return_if_fail (GTK_IS_WIDGET (widget));
1198 gtk_object_setv (GTK_OBJECT (widget), nargs, args);
1201 /*****************************************
1202 * gtk_widget_unparent:
1203 * do any cleanup necessary necessary
1204 * for setting parent = NULL.
1209 *****************************************/
1212 gtk_widget_unparent (GtkWidget *widget)
1214 GtkWidget *toplevel;
1215 GtkWidget *old_parent;
1217 g_return_if_fail (widget != NULL);
1218 g_return_if_fail (GTK_IS_WIDGET (widget));
1219 if (widget->parent == NULL)
1222 /* keep this function in sync with gtk_menu_detach()
1225 /* unset focused and default children properly, this code
1226 * should eventually move into some gtk_window_unparent_branch() or
1230 toplevel = gtk_widget_get_toplevel (widget);
1231 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
1233 gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
1235 if (GTK_IS_WINDOW (toplevel))
1239 child = GTK_WINDOW (toplevel)->focus_widget;
1241 while (child && child != widget)
1242 child = child->parent;
1244 if (child == widget)
1245 gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
1248 if (GTK_IS_WINDOW (toplevel))
1252 child = GTK_WINDOW (toplevel)->default_widget;
1254 while (child && child != widget)
1255 child = child->parent;
1257 if (child == widget)
1258 gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
1261 if (GTK_WIDGET_REDRAW_PENDING (widget))
1262 gtk_widget_redraw_queue_remove (widget);
1264 if (GTK_IS_RESIZE_CONTAINER (widget))
1265 gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
1267 /* Remove the widget and all its children from any ->resize_widgets list
1268 * of all the parents in our branch. This code should move into gtkcontainer.c
1269 * somwhen, since we mess around with ->resize_widgets, which is
1270 * actually not of our business.
1272 * Two ways to make this prettier:
1273 * Write a g_slist_conditional_remove (GSList, gboolean (*)(gpointer))
1274 * Change resize_widgets to a GList
1276 toplevel = widget->parent;
1282 if (!GTK_CONTAINER (toplevel)->resize_widgets)
1284 toplevel = toplevel->parent;
1289 slist = GTK_CONTAINER (toplevel)->resize_widgets;
1301 while (parent && (parent != widget))
1302 parent = parent->parent;
1304 if (parent == widget)
1306 GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
1312 /* it is really messy to have this signal disconnection
1313 * in gtkwidget.c, the resize_widgets invariants should
1314 * all be taken care off by gtkcontainer.c exclusively.
1317 gtk_signal_disconnect_by_func (GTK_OBJECT (toplevel),
1318 GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets),
1320 GTK_CONTAINER (toplevel)->resize_widgets = slist;
1323 g_slist_free_1 (last);
1329 toplevel = toplevel->parent;
1331 if (widget->window &&
1332 GTK_WIDGET_NO_WINDOW (widget) &&
1333 GTK_WIDGET_DRAWABLE (widget))
1334 gtk_widget_queue_clear (widget);
1336 /* Reset the width and height here, to force reallocation if we
1337 * get added back to a new parent. This won't work if our new
1338 * allocation is smaller than 1x1 and we actually want a size of 1x1...
1339 * (would 0x0 be OK here?)
1341 widget->allocation.width = 1;
1342 widget->allocation.height = 1;
1344 if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_IN_REPARENT (widget))
1345 gtk_widget_unrealize (widget);
1347 old_parent = widget->parent;
1348 widget->parent = NULL;
1349 gtk_widget_set_parent_window (widget, NULL);
1350 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], old_parent);
1352 gtk_widget_unref (widget);
1355 /*****************************************
1356 * gtk_widget_destroy:
1361 *****************************************/
1364 gtk_widget_destroy (GtkWidget *widget)
1366 g_return_if_fail (widget != NULL);
1367 g_return_if_fail (GTK_IS_WIDGET (widget));
1368 g_return_if_fail (GTK_OBJECT_CONSTRUCTED (widget));
1370 gtk_object_destroy ((GtkObject*) widget);
1373 /*****************************************
1374 * gtk_widget_destroyed:
1375 * Utility function: sets widget_pointer
1376 * to NULL when widget is destroyed.
1381 *****************************************/
1384 gtk_widget_destroyed (GtkWidget *widget,
1385 GtkWidget **widget_pointer)
1387 /* Don't make any assumptions about the
1389 * Even check widget_pointer.
1392 *widget_pointer = NULL;
1395 /*****************************************
1401 *****************************************/
1404 gtk_widget_show (GtkWidget *widget)
1406 g_return_if_fail (widget != NULL);
1407 g_return_if_fail (GTK_IS_WIDGET (widget));
1409 if (!GTK_WIDGET_VISIBLE (widget))
1410 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SHOW]);
1414 /*************************************************************
1415 * gtk_widget_show_now:
1416 * Show a widget, and if it is an unmapped toplevel widget
1417 * wait for the map_event before returning
1419 * Warning: This routine will call the main loop recursively.
1424 *************************************************************/
1427 gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
1430 gtk_signal_disconnect_by_data (GTK_OBJECT (widget), flag);
1434 gtk_widget_show_now (GtkWidget *widget)
1438 g_return_if_fail (widget != NULL);
1439 g_return_if_fail (GTK_IS_WIDGET (widget));
1441 /* make sure we will get event */
1442 if (!GTK_WIDGET_MAPPED (widget) &&
1443 GTK_WIDGET_TOPLEVEL (widget))
1445 gtk_widget_show (widget);
1447 gtk_signal_connect (GTK_OBJECT (widget), "map_event",
1448 GTK_SIGNAL_FUNC (gtk_widget_show_map_callback),
1452 gtk_main_iteration();
1455 gtk_widget_show (widget);
1458 /*****************************************
1464 *****************************************/
1467 gtk_widget_hide (GtkWidget *widget)
1469 g_return_if_fail (widget != NULL);
1470 g_return_if_fail (GTK_IS_WIDGET (widget));
1472 if (GTK_WIDGET_VISIBLE (widget))
1473 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[HIDE]);
1477 gtk_widget_hide_on_delete (GtkWidget *widget)
1479 g_return_val_if_fail (widget != NULL, FALSE);
1480 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1482 gtk_widget_hide (widget);
1488 gtk_widget_show_all (GtkWidget *widget)
1490 GtkWidgetClass *class;
1492 g_return_if_fail (widget != NULL);
1493 g_return_if_fail (GTK_IS_WIDGET (widget));
1495 class = GTK_WIDGET_CLASS (GTK_OBJECT (widget)->klass);
1497 if (class->show_all)
1498 class->show_all (widget);
1502 gtk_widget_hide_all (GtkWidget *widget)
1504 GtkWidgetClass *class;
1506 g_return_if_fail (widget != NULL);
1507 g_return_if_fail (GTK_IS_WIDGET (widget));
1509 class = GTK_WIDGET_CLASS (GTK_OBJECT (widget)->klass);
1511 if (class->hide_all)
1512 class->hide_all (widget);
1515 /*****************************************
1521 *****************************************/
1524 gtk_widget_map (GtkWidget *widget)
1526 g_return_if_fail (widget != NULL);
1527 g_return_if_fail (GTK_IS_WIDGET (widget));
1529 if (!GTK_WIDGET_MAPPED (widget))
1531 if (!GTK_WIDGET_REALIZED (widget))
1532 gtk_widget_realize (widget);
1534 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
1538 /*****************************************
1544 *****************************************/
1547 gtk_widget_unmap (GtkWidget *widget)
1549 g_return_if_fail (widget != NULL);
1550 g_return_if_fail (GTK_IS_WIDGET (widget));
1552 if (GTK_WIDGET_MAPPED (widget))
1553 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
1556 /*****************************************
1557 * gtk_widget_realize:
1562 *****************************************/
1565 gtk_widget_realize (GtkWidget *widget)
1568 GdkExtensionMode mode;
1569 GtkWidgetShapeInfo *shape_info;
1571 g_return_if_fail (widget != NULL);
1572 g_return_if_fail (GTK_IS_WIDGET (widget));
1574 if (!GTK_WIDGET_REALIZED (widget))
1577 if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
1578 g_message ("gtk_widget_realize(%s)", gtk_type_name (GTK_WIDGET_TYPE (widget)));
1581 if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
1582 gtk_widget_realize (widget->parent);
1584 gtk_widget_ensure_style (widget);
1586 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);
1588 if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1590 shape_info = gtk_object_get_data (GTK_OBJECT (widget),
1592 gdk_window_shape_combine_mask (widget->window,
1593 shape_info->shape_mask,
1594 shape_info->offset_x,
1595 shape_info->offset_y);
1598 if (!GTK_WIDGET_NO_WINDOW (widget))
1600 mode = gtk_widget_get_extension_events (widget);
1601 if (mode != GDK_EXTENSION_EVENTS_NONE)
1603 events = gtk_widget_get_events (widget);
1604 gdk_input_set_extension_events (widget->window, events, mode);
1611 /*****************************************
1612 * gtk_widget_unrealize:
1617 *****************************************/
1620 gtk_widget_unrealize (GtkWidget *widget)
1622 g_return_if_fail (widget != NULL);
1623 g_return_if_fail (GTK_IS_WIDGET (widget));
1625 if (GTK_WIDGET_REDRAW_PENDING (widget))
1626 gtk_widget_redraw_queue_remove (widget);
1628 if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1629 gtk_widget_shape_combine_mask (widget, NULL, -1, -1);
1631 if (GTK_WIDGET_REALIZED (widget))
1633 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);
1634 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
1638 /*****************************************
1639 * gtk_widget_queue_draw:
1644 *****************************************/
1646 typedef struct _GtkDrawData GtkDrawData;
1647 struct _GtkDrawData {
1652 static GMemChunk *draw_data_mem_chunk = NULL;
1653 static GSList *draw_data_free_list = NULL;
1654 static const gchar *draw_data_key = "gtk-draw-data";
1655 static GQuark draw_data_key_id = 0;
1657 static gint gtk_widget_idle_draw (gpointer data);
1660 gtk_widget_queue_draw_data (GtkWidget *widget,
1670 g_return_if_fail (widget != NULL);
1672 if ((width != 0) && (height != 0) && GTK_WIDGET_DRAWABLE (widget))
1674 if (!draw_data_key_id)
1675 draw_data_key_id = g_quark_from_static_string (draw_data_key);
1677 if (draw_data_free_list)
1679 node = draw_data_free_list;
1681 draw_data_free_list = draw_data_free_list->next;
1685 if (!draw_data_mem_chunk)
1686 draw_data_mem_chunk = g_mem_chunk_create (GtkDrawData, 64,
1688 data = g_chunk_new (GtkDrawData, draw_data_mem_chunk);
1689 node = g_slist_alloc();
1696 if ((width < 0) || (height < 0))
1698 data->rect.width = 0;
1699 data->rect.height = 0;
1703 data->rect.width = width;
1704 data->rect.height = height;
1706 data->window = window;
1708 if ((width < 0) || (height < 0))
1710 GSList *draw_data_list =
1711 gtk_object_get_data_by_id (GTK_OBJECT (widget),
1714 draw_data_free_list = g_slist_concat (draw_data_list,
1715 draw_data_free_list);
1719 node->next = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1722 if (!GTK_WIDGET_REDRAW_PENDING (widget))
1724 GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_PENDING);
1725 if (gtk_widget_redraw_queue == NULL)
1726 gtk_idle_add_priority (GTK_PRIORITY_INTERNAL,
1727 gtk_widget_idle_draw,
1729 gtk_widget_redraw_queue = g_slist_prepend (gtk_widget_redraw_queue, widget);
1732 gtk_object_set_data_by_id (GTK_OBJECT (widget), draw_data_key_id, node);
1737 gtk_widget_queue_draw_area (GtkWidget *widget,
1743 g_return_if_fail (widget != NULL);
1744 g_return_if_fail (GTK_IS_WIDGET (widget));
1746 gtk_widget_queue_draw_data (widget, x, y, width, height, NULL);
1750 gtk_widget_queue_draw (GtkWidget *widget)
1752 g_return_if_fail (widget != NULL);
1753 g_return_if_fail (GTK_IS_WIDGET (widget));
1755 gtk_widget_queue_draw_data (widget, 0, 0, -1, -1, NULL);
1759 gtk_widget_queue_clear_area (GtkWidget *widget,
1767 g_return_if_fail (widget != NULL);
1768 g_return_if_fail (GTK_IS_WIDGET (widget));
1770 /* Find the correct widget */
1772 if (GTK_WIDGET_NO_WINDOW (widget))
1775 while (parent && GTK_WIDGET_NO_WINDOW (parent))
1776 parent = parent->parent;
1779 gtk_widget_queue_draw_data (parent, x, y, width, height, widget->window);
1783 gint wx, wy, wwidth, wheight;
1784 /* Translate widget relative to window-relative */
1786 gdk_window_get_position (widget->window, &wx, &wy);
1787 x -= wx - widget->allocation.x;
1788 y -= wy - widget->allocation.y;
1790 gdk_window_get_size (widget->window, &wwidth, &wheight);
1800 if (x + width > wwidth)
1802 if (y + height > wheight)
1803 height = wheight - y;
1805 gtk_widget_queue_draw_data (widget, x, y, width, height, NULL);
1810 gtk_widget_redraw_queue_remove (GtkWidget *widget)
1812 GSList *draw_data_list;
1815 g_return_if_fail (GTK_WIDGET_REDRAW_PENDING (widget));
1817 gtk_widget_redraw_queue = g_slist_remove (gtk_widget_redraw_queue, widget);
1819 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1821 tmp_list = g_slist_last (draw_data_list);
1824 tmp_list->next = draw_data_free_list;
1825 draw_data_free_list = draw_data_list;
1828 gtk_object_set_data_by_id (GTK_OBJECT (widget),
1832 GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
1836 gtk_widget_queue_clear (GtkWidget *widget)
1838 g_return_if_fail (widget != NULL);
1839 g_return_if_fail (GTK_IS_WIDGET (widget));
1841 if (GTK_WIDGET_NO_WINDOW (widget))
1842 gtk_widget_queue_clear_area (widget, widget->allocation.x,
1843 widget->allocation.y,
1844 widget->allocation.width,
1845 widget->allocation.height);
1847 gtk_widget_queue_clear_area (widget, 0, 0,
1848 widget->allocation.width,
1849 widget->allocation.height);
1853 gtk_widget_draw_data_combine (GtkDrawData *parent, GtkDrawData *child)
1855 gint parent_x2, parent_y2;
1856 gint child_x2, child_y2;
1858 /* Check for intersection */
1860 parent_x2 = parent->rect.x + parent->rect.width;
1861 child_x2 = child->rect.x + child->rect.width;
1862 parent_y2 = parent->rect.y + parent->rect.height;
1863 child_y2 = child->rect.y + child->rect.height;
1865 if ((child->rect.x > parent_x2) || (parent->rect.x > child_x2) ||
1866 (child->rect.y > parent_y2) || (parent->rect.y > child_y2))
1870 parent->rect.x = MIN (parent->rect.x, child->rect.x);
1871 parent->rect.y = MIN (parent->rect.y, child->rect.y);
1872 parent->rect.width = MAX (parent_x2, child_x2) - parent->rect.x;
1873 parent->rect.height = MAX (parent_y2, child_y2) - parent->rect.y;
1879 /* Take a rectangle with respect to window, and translate it
1880 * to coordinates relative to widget's allocation, clipping through
1881 * intermediate windows. Returns whether translation failed. If the
1882 * translation failed, we have something like a handlebox, where
1883 * the child widget's GdkWindow is not a child of the parents GdkWindow.
1886 gtk_widget_clip_rect (GtkWidget *widget,
1892 gint x,y, width, height;
1894 while (window && (window != widget->window))
1896 gdk_window_get_position (window, &x, &y);
1904 window = gdk_window_get_parent (window);
1908 gdk_window_get_size (window, &width, &height);
1912 rect->width += rect->x;
1917 rect->height += rect->y;
1920 if (rect->x + rect->width > width)
1921 rect->width = width - rect->x;
1922 if (rect->y + rect->height > height)
1923 rect->height = height - rect->y;
1929 if (!GTK_WIDGET_NO_WINDOW (widget))
1931 if (gdk_window_get_toplevel (window) != window)
1933 gdk_window_get_position (window, &x, &y);
1934 rect->x += x - widget->allocation.x;
1936 *x_offset += x - widget->allocation.x;
1937 rect->y += y - widget->allocation.y;
1939 *y_offset += y - widget->allocation.y;
1947 gtk_widget_idle_draw (gpointer data)
1949 GSList *widget_list;
1950 GSList *draw_data_list;
1953 /* Translate all draw requests to be allocation-relative */
1954 widget_list = gtk_widget_redraw_queue;
1957 widget = widget_list->data;
1958 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1961 while (draw_data_list)
1963 gboolean full_allocation = FALSE;
1964 GtkDrawData *data = draw_data_list->data;
1968 /* If the translation fails, we have a handlebox,
1969 * so redraw the whole widget. Could be done better?
1971 full_allocation = !gtk_widget_clip_rect (widget,
1975 data->window = NULL;
1979 if ((data->rect.width == 0) && (data->rect.height == 0))
1981 if (GTK_WIDGET_NO_WINDOW (widget))
1983 data->rect.x = widget->allocation.x;
1984 data->rect.y = widget->allocation.y;
1991 data->rect.width = widget->allocation.width;
1992 data->rect.height = widget->allocation.height;
1996 draw_data_list = draw_data_list->next;
1999 widget_list = widget_list->next;
2004 widget_list = gtk_widget_redraw_queue;
2007 GSList *prev_node = NULL;
2008 widget = widget_list->data;
2009 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
2012 while (draw_data_list)
2014 gint x_offset, y_offset;
2015 GtkDrawData *data = draw_data_list->data;
2016 GSList *parent_list = draw_data_list->next;
2028 if (gtk_widget_draw_data_combine (parent_list->data, data))
2032 prev_node->next = draw_data_list->next;
2034 gtk_object_set_data_by_id (GTK_OBJECT (widget),
2036 draw_data_list->next);
2038 tmp = draw_data_list->next;
2039 draw_data_list->next = draw_data_free_list;
2040 draw_data_free_list = draw_data_list;
2041 draw_data_list = tmp;
2046 parent_list = parent_list->next;
2049 window = parent->window;
2051 if (parent->parent && parent->parent->window != window)
2053 if (!GTK_WIDGET_NO_WINDOW (parent))
2056 gdk_window_get_position (window, &x, &y);
2057 data->rect.x -= x - parent->allocation.x;
2058 x_offset -= x - parent->allocation.x;
2059 data->rect.y -= y - parent->allocation.y;
2060 y_offset -= y - parent->allocation.y;
2062 /* If we can't translate the rectangle, stop trying to
2063 * merge. (This occurs for a handlebox)
2065 if (!gtk_widget_clip_rect (parent->parent, window, &data->rect,
2066 &x_offset, &y_offset))
2071 parent = parent->parent;
2073 if (parent && GTK_WIDGET_REDRAW_PENDING (parent))
2074 parent_list = gtk_object_get_data_by_id (GTK_OBJECT (parent),
2080 /* OK, this rectangle stays around. But take advantage
2081 * of the work we've done to clip it to the visible area -
2082 * rect.width/height have already been appropriately
2085 data->rect.x -= x_offset;
2086 data->rect.y -= y_offset;
2089 prev_node = draw_data_list;
2091 draw_data_list = draw_data_list->next;
2095 widget_list = widget_list->next;
2098 /* Process the draws */
2100 widget_list = gtk_widget_redraw_queue;
2104 widget = widget_list->data;
2105 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
2107 gtk_object_set_data_by_id (GTK_OBJECT (widget),
2111 GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
2113 while (draw_data_list)
2115 GtkDrawData *data = draw_data_list->data;
2116 gtk_widget_draw (widget, &data->rect);
2118 if (draw_data_list->next)
2119 draw_data_list = draw_data_list->next;
2122 draw_data_list->next = draw_data_free_list;
2123 draw_data_free_list = draw_data_list;
2128 widget_list = widget_list->next;
2131 g_slist_free (gtk_widget_redraw_queue);
2132 gtk_widget_redraw_queue = NULL;
2138 gtk_widget_queue_resize (GtkWidget *widget)
2140 g_return_if_fail (widget != NULL);
2141 g_return_if_fail (GTK_IS_WIDGET (widget));
2143 if (GTK_IS_RESIZE_CONTAINER (widget))
2144 gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
2147 gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
2148 else if (GTK_WIDGET_TOPLEVEL (widget))
2149 gtk_container_queue_resize (GTK_CONTAINER (widget));
2152 /*****************************************
2158 *****************************************/
2161 gtk_widget_draw (GtkWidget *widget,
2164 GdkRectangle temp_area;
2166 g_return_if_fail (widget != NULL);
2167 g_return_if_fail (GTK_IS_WIDGET (widget));
2169 if (GTK_WIDGET_DRAWABLE (widget))
2173 if (GTK_WIDGET_NO_WINDOW (widget))
2175 temp_area.x = widget->allocation.x;
2176 temp_area.y = widget->allocation.y;
2184 temp_area.width = widget->allocation.width;
2185 temp_area.height = widget->allocation.height;
2189 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area);
2193 /*****************************************
2194 * gtk_widget_draw_focus:
2199 *****************************************/
2202 gtk_widget_draw_focus (GtkWidget *widget)
2204 g_return_if_fail (widget != NULL);
2205 g_return_if_fail (GTK_IS_WIDGET (widget));
2207 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_FOCUS]);
2210 /*****************************************
2211 * gtk_widget_draw_default:
2216 *****************************************/
2219 gtk_widget_draw_default (GtkWidget *widget)
2221 g_return_if_fail (widget != NULL);
2222 g_return_if_fail (GTK_IS_WIDGET (widget));
2224 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_DEFAULT]);
2227 /*****************************************
2228 * gtk_widget_size_request:
2233 *****************************************/
2236 gtk_widget_size_request (GtkWidget *widget,
2237 GtkRequisition *requisition)
2239 GtkWidgetAuxInfo *aux_info;
2241 g_return_if_fail (widget != NULL);
2242 g_return_if_fail (GTK_IS_WIDGET (widget));
2244 gtk_widget_ref (widget);
2245 gtk_widget_ensure_style (widget);
2246 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST],
2248 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
2251 if (aux_info->width > 0)
2252 requisition->width = aux_info->width;
2253 if (aux_info->height > 0)
2254 requisition->height = aux_info->height;
2256 gtk_widget_unref (widget);
2259 /*****************************************
2260 * gtk_widget_size_allocate:
2265 *****************************************/
2268 gtk_widget_size_allocate (GtkWidget *widget,
2269 GtkAllocation *allocation)
2271 GtkWidgetAuxInfo *aux_info;
2272 GtkAllocation real_allocation;
2274 g_return_if_fail (widget != NULL);
2275 g_return_if_fail (GTK_IS_WIDGET (widget));
2277 real_allocation = *allocation;
2278 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
2282 if (aux_info->x != -1)
2283 real_allocation.x = aux_info->x;
2284 if (aux_info->y != -1)
2285 real_allocation.y = aux_info->y;
2288 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
2292 gtk_widget_stop_add_accelerator (GtkWidget *widget)
2294 g_return_if_fail (widget != NULL);
2295 g_return_if_fail (GTK_IS_WIDGET (widget));
2297 gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[ADD_ACCELERATOR]);
2301 gtk_widget_stop_remove_accelerator (GtkWidget *widget)
2303 g_return_if_fail (widget != NULL);
2304 g_return_if_fail (GTK_IS_WIDGET (widget));
2306 gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR]);
2310 gtk_widget_lock_accelerators (GtkWidget *widget)
2312 g_return_if_fail (widget != NULL);
2313 g_return_if_fail (GTK_IS_WIDGET (widget));
2315 if (gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
2316 widget_signals[ADD_ACCELERATOR],
2318 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2321 gtk_signal_connect (GTK_OBJECT (widget),
2323 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2325 gtk_signal_connect (GTK_OBJECT (widget),
2326 "remove_accelerator",
2327 GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2333 gtk_widget_unlock_accelerators (GtkWidget *widget)
2335 g_return_if_fail (widget != NULL);
2336 g_return_if_fail (GTK_IS_WIDGET (widget));
2338 if (gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
2339 widget_signals[ADD_ACCELERATOR],
2341 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2344 gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2345 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2347 gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2348 GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2354 gtk_widget_thaw_accelerators (GtkWidget *widget)
2356 g_message ("gtk_widget_thaw_accelerators() is deprecated");
2358 gtk_widget_unlock_accelerators (widget);
2362 gtk_widget_freeze_accelerators (GtkWidget *widget)
2364 g_message ("gtk_widget_freeze_accelerators() is deprecated");
2366 gtk_widget_lock_accelerators (widget);
2370 gtk_widget_add_accelerator (GtkWidget *widget,
2371 const gchar *accel_signal,
2372 GtkAccelGroup *accel_group,
2375 GtkAccelFlags accel_flags)
2377 g_return_if_fail (widget != NULL);
2378 g_return_if_fail (GTK_IS_WIDGET (widget));
2379 g_return_if_fail (accel_group != NULL);
2381 gtk_accel_group_add (accel_group,
2385 (GtkObject*) widget,
2390 gtk_widget_remove_accelerator (GtkWidget *widget,
2391 GtkAccelGroup *accel_group,
2395 g_return_if_fail (widget != NULL);
2396 g_return_if_fail (GTK_IS_WIDGET (widget));
2397 g_return_if_fail (accel_group != NULL);
2399 gtk_accel_group_remove (accel_group,
2402 (GtkObject*) widget);
2406 gtk_widget_remove_accelerators (GtkWidget *widget,
2407 const gchar *accel_signal,
2408 gboolean visible_only)
2413 g_return_if_fail (widget != NULL);
2414 g_return_if_fail (GTK_IS_WIDGET (widget));
2415 g_return_if_fail (accel_signal != NULL);
2417 signal_id = gtk_signal_lookup (accel_signal, GTK_OBJECT_TYPE (widget));
2418 g_return_if_fail (signal_id != 0);
2420 slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget));
2423 GtkAccelEntry *ac_entry;
2425 ac_entry = slist->data;
2426 slist = slist->next;
2427 if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE &&
2428 ac_entry->signal_id == signal_id)
2429 gtk_widget_remove_accelerator (GTK_WIDGET (widget),
2430 ac_entry->accel_group,
2431 ac_entry->accelerator_key,
2432 ac_entry->accelerator_mods);
2437 gtk_widget_accelerator_signal (GtkWidget *widget,
2438 GtkAccelGroup *accel_group,
2442 GtkAccelEntry *ac_entry;
2444 g_return_val_if_fail (widget != NULL, 0);
2445 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
2446 g_return_val_if_fail (accel_group != NULL, 0);
2448 ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods);
2450 if (ac_entry && ac_entry->object == (GtkObject*) widget)
2451 return ac_entry->signal_id;
2456 gtk_widget_real_key_press_event (GtkWidget *widget,
2459 gboolean handled = FALSE;
2461 g_return_val_if_fail (widget != NULL, handled);
2462 g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2463 g_return_val_if_fail (event != NULL, handled);
2466 handled = gtk_bindings_activate (GTK_OBJECT (widget),
2474 gtk_widget_real_key_release_event (GtkWidget *widget,
2477 gboolean handled = FALSE;
2479 g_return_val_if_fail (widget != NULL, handled);
2480 g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2481 g_return_val_if_fail (event != NULL, handled);
2484 handled = gtk_bindings_activate (GTK_OBJECT (widget),
2486 event->state | GDK_RELEASE_MASK);
2491 /*****************************************
2497 *****************************************/
2500 gtk_widget_event (GtkWidget *widget,
2506 g_return_val_if_fail (widget != NULL, TRUE);
2507 g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
2509 gtk_widget_ref (widget);
2511 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event,
2513 if (return_val || GTK_OBJECT_DESTROYED (widget))
2515 gtk_widget_unref (widget);
2519 switch (event->type)
2524 case GDK_BUTTON_PRESS:
2525 case GDK_2BUTTON_PRESS:
2526 case GDK_3BUTTON_PRESS:
2527 signal_num = BUTTON_PRESS_EVENT;
2529 case GDK_BUTTON_RELEASE:
2530 signal_num = BUTTON_RELEASE_EVENT;
2532 case GDK_MOTION_NOTIFY:
2533 signal_num = MOTION_NOTIFY_EVENT;
2536 signal_num = DELETE_EVENT;
2539 signal_num = DESTROY_EVENT;
2542 signal_num = KEY_PRESS_EVENT;
2544 case GDK_KEY_RELEASE:
2545 signal_num = KEY_RELEASE_EVENT;
2547 case GDK_ENTER_NOTIFY:
2548 signal_num = ENTER_NOTIFY_EVENT;
2550 case GDK_LEAVE_NOTIFY:
2551 signal_num = LEAVE_NOTIFY_EVENT;
2553 case GDK_FOCUS_CHANGE:
2554 if (event->focus_change.in)
2555 signal_num = FOCUS_IN_EVENT;
2557 signal_num = FOCUS_OUT_EVENT;
2560 signal_num = CONFIGURE_EVENT;
2563 signal_num = MAP_EVENT;
2566 signal_num = UNMAP_EVENT;
2568 case GDK_PROPERTY_NOTIFY:
2569 signal_num = PROPERTY_NOTIFY_EVENT;
2571 case GDK_SELECTION_CLEAR:
2572 signal_num = SELECTION_CLEAR_EVENT;
2574 case GDK_SELECTION_REQUEST:
2575 signal_num = SELECTION_REQUEST_EVENT;
2577 case GDK_SELECTION_NOTIFY:
2578 signal_num = SELECTION_NOTIFY_EVENT;
2580 case GDK_PROXIMITY_IN:
2581 signal_num = PROXIMITY_IN_EVENT;
2583 case GDK_PROXIMITY_OUT:
2584 signal_num = PROXIMITY_OUT_EVENT;
2587 signal_num = NO_EXPOSE_EVENT;
2589 case GDK_CLIENT_EVENT:
2590 signal_num = CLIENT_EVENT;
2593 /* there is no sense in providing a widget with bogus expose events.
2594 * Widgets that are going to be resized don't need to be
2595 * exposed, since they will be redrawn anyways.
2597 if (!event->any.window ||
2598 GTK_WIDGET_RESIZE_NEEDED (widget) ||
2599 (widget->parent && GTK_WIDGET_RESIZE_NEEDED (widget->parent)))
2601 gtk_widget_unref (widget);
2604 signal_num = EXPOSE_EVENT;
2606 case GDK_VISIBILITY_NOTIFY:
2607 signal_num = VISIBILITY_NOTIFY_EVENT;
2610 g_warning ("could not determine signal number for event: %d", event->type);
2611 gtk_widget_unref (widget);
2615 if (signal_num != -1)
2616 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val);
2618 return_val |= GTK_OBJECT_DESTROYED (widget);
2620 gtk_widget_unref (widget);
2625 /*****************************************
2626 * gtk_widget_activate:
2631 *****************************************/
2634 gtk_widget_activate (GtkWidget *widget)
2636 g_return_val_if_fail (widget != NULL, FALSE);
2637 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2639 if (WIDGET_CLASS (widget)->activate_signal)
2641 /* FIXME: we should eventually check the signals signature here */
2642 gtk_signal_emit (GTK_OBJECT (widget), WIDGET_CLASS (widget)->activate_signal);
2651 gtk_widget_set_scroll_adjustments (GtkWidget *widget,
2652 GtkAdjustment *hadjustment,
2653 GtkAdjustment *vadjustment)
2655 g_return_val_if_fail (widget != NULL, FALSE);
2656 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2658 g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), FALSE);
2660 g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), FALSE);
2662 if (WIDGET_CLASS (widget)->set_scroll_adjustments_signal)
2664 /* FIXME: we should eventually check the signals signature here */
2665 gtk_signal_emit (GTK_OBJECT (widget),
2666 WIDGET_CLASS (widget)->set_scroll_adjustments_signal,
2667 hadjustment, vadjustment);
2674 /*****************************************
2675 * gtk_widget_reparent_container_child:
2676 * assistent function to gtk_widget_reparent
2681 *****************************************/
2684 gtk_widget_reparent_container_child (GtkWidget *widget,
2685 gpointer client_data)
2687 g_return_if_fail (widget != NULL);
2688 g_return_if_fail (GTK_IS_WIDGET (widget));
2689 g_return_if_fail (client_data != NULL);
2691 if (GTK_WIDGET_NO_WINDOW (widget))
2694 gdk_window_unref (widget->window);
2695 widget->window = (GdkWindow*) client_data;
2697 gdk_window_ref (widget->window);
2699 if (GTK_IS_CONTAINER (widget))
2700 gtk_container_forall (GTK_CONTAINER (widget),
2701 gtk_widget_reparent_container_child,
2705 gdk_window_reparent (widget->window,
2706 (GdkWindow*) client_data, 0, 0);
2709 /*****************************************
2710 * gtk_widget_reparent:
2715 *****************************************/
2718 gtk_widget_reparent (GtkWidget *widget,
2719 GtkWidget *new_parent)
2721 g_return_if_fail (widget != NULL);
2722 g_return_if_fail (GTK_IS_WIDGET (widget));
2723 g_return_if_fail (new_parent != NULL);
2724 g_return_if_fail (GTK_IS_CONTAINER (new_parent));
2725 g_return_if_fail (widget->parent != NULL);
2727 if (widget->parent != new_parent)
2729 /* First try to see if we can get away without unrealizing
2730 * the widget as we reparent it. if so we set a flag so
2731 * that gtk_widget_unparent doesn't unrealize widget
2733 if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
2734 GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
2736 gtk_widget_ref (widget);
2737 gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
2738 gtk_container_add (GTK_CONTAINER (new_parent), widget);
2739 gtk_widget_unref (widget);
2741 if (GTK_WIDGET_IN_REPARENT (widget))
2743 GTK_PRIVATE_UNSET_FLAG (widget, GTK_IN_REPARENT);
2745 /* OK, now fix up the widget's window. (And that for any
2746 * children, if the widget is NO_WINDOW and a container)
2748 if (GTK_WIDGET_NO_WINDOW (widget))
2750 if (GTK_IS_CONTAINER (widget))
2751 gtk_container_forall (GTK_CONTAINER (widget),
2752 gtk_widget_reparent_container_child,
2753 gtk_widget_get_parent_window (widget));
2756 GdkWindow *parent_window;
2758 parent_window = gtk_widget_get_parent_window (widget);
2759 if (parent_window != widget->window)
2762 gdk_window_unref (widget->window);
2763 widget->window = parent_window;
2765 gdk_window_ref (widget->window);
2770 gdk_window_reparent (widget->window, gtk_widget_get_parent_window (widget), 0, 0);
2775 /*****************************************
2781 *****************************************/
2784 gtk_widget_popup (GtkWidget *widget,
2788 g_return_if_fail (widget != NULL);
2789 g_return_if_fail (GTK_IS_WIDGET (widget));
2791 if (!GTK_WIDGET_VISIBLE (widget))
2793 if (!GTK_WIDGET_REALIZED (widget))
2794 gtk_widget_realize (widget);
2795 if (!GTK_WIDGET_NO_WINDOW (widget))
2796 gdk_window_move (widget->window, x, y);
2797 gtk_widget_show (widget);
2801 /*****************************************
2802 * gtk_widget_intersect:
2807 *****************************************/
2810 gtk_widget_intersect (GtkWidget *widget,
2812 GdkRectangle *intersection)
2818 g_return_val_if_fail (widget != NULL, FALSE);
2819 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2820 g_return_val_if_fail (area != NULL, FALSE);
2823 dest = intersection;
2827 return_val = gdk_rectangle_intersect ((GdkRectangle*) &widget->allocation, area, dest);
2829 if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
2831 intersection->x -= widget->allocation.x;
2832 intersection->y -= widget->allocation.y;
2838 /*****************************************
2839 * gtk_widget_grab_focus:
2844 *****************************************/
2847 gtk_widget_grab_focus (GtkWidget *widget)
2849 g_return_if_fail (widget != NULL);
2850 g_return_if_fail (GTK_IS_WIDGET (widget));
2852 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[GRAB_FOCUS]);
2856 reset_focus_recurse (GtkWidget *widget,
2859 if (GTK_IS_CONTAINER (widget))
2861 GtkContainer *container;
2863 container = GTK_CONTAINER (widget);
2864 gtk_container_set_focus_child (container, NULL);
2866 gtk_container_foreach (container,
2867 reset_focus_recurse,
2873 gtk_widget_real_grab_focus (GtkWidget *focus_widget)
2875 g_return_if_fail (focus_widget != NULL);
2876 g_return_if_fail (GTK_IS_WIDGET (focus_widget));
2878 if (GTK_WIDGET_CAN_FOCUS (focus_widget))
2880 GtkWidget *toplevel;
2883 /* clear the current focus setting, break if the current widget
2884 * is the focus widget's parent, since containers above that will
2885 * be set by the next loop.
2887 toplevel = gtk_widget_get_toplevel (focus_widget);
2888 if (GTK_IS_WINDOW (toplevel))
2890 widget = GTK_WINDOW (toplevel)->focus_widget;
2892 if (widget == focus_widget)
2897 while (widget->parent && widget->parent != focus_widget->parent)
2899 widget = widget->parent;
2900 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
2904 else if (toplevel != focus_widget)
2906 /* gtk_widget_grab_focus() operates on a tree without window...
2907 * actually, this is very questionable behaviour.
2910 gtk_container_foreach (GTK_CONTAINER (toplevel),
2911 reset_focus_recurse,
2915 /* now propagate the new focus up the widget tree and finally
2916 * set it on the window
2918 widget = focus_widget;
2919 while (widget->parent)
2921 gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), widget);
2922 widget = widget->parent;
2924 if (GTK_IS_WINDOW (widget))
2925 gtk_window_set_focus (GTK_WINDOW (widget), focus_widget);
2929 /*****************************************
2930 * gtk_widget_grab_default:
2935 *****************************************/
2938 gtk_widget_grab_default (GtkWidget *widget)
2941 GtkType window_type;
2943 g_return_if_fail (widget != NULL);
2944 g_return_if_fail (GTK_IS_WIDGET (widget));
2945 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
2947 window_type = gtk_window_get_type ();
2948 window = widget->parent;
2950 while (window && !gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2951 window = window->parent;
2953 if (window && gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2954 gtk_window_set_default (GTK_WINDOW (window), widget);
2957 /*****************************************
2958 * gtk_widget_set_name:
2963 *****************************************/
2966 gtk_widget_set_name (GtkWidget *widget,
2969 g_return_if_fail (widget != NULL);
2970 g_return_if_fail (GTK_IS_WIDGET (widget));
2973 g_free (widget->name);
2974 widget->name = g_strdup (name);
2976 if (!GTK_WIDGET_USER_STYLE (widget))
2977 gtk_widget_set_rc_style (widget);
2980 /*****************************************
2981 * gtk_widget_get_name:
2986 *****************************************/
2989 gtk_widget_get_name (GtkWidget *widget)
2991 g_return_val_if_fail (widget != NULL, NULL);
2992 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2995 return widget->name;
2996 return gtk_type_name (GTK_WIDGET_TYPE (widget));
2999 /*****************************************
3000 * gtk_widget_set_state:
3007 *****************************************/
3010 gtk_widget_set_state (GtkWidget *widget,
3013 g_return_if_fail (widget != NULL);
3014 g_return_if_fail (GTK_IS_WIDGET (widget));
3016 if (state == GTK_WIDGET_STATE (widget))
3019 if (state == GTK_STATE_INSENSITIVE)
3020 gtk_widget_set_sensitive (widget, FALSE);
3026 data.state_restoration = FALSE;
3027 data.use_forall = FALSE;
3029 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
3031 data.parent_sensitive = TRUE;
3033 gtk_widget_propagate_state (widget, &data);
3035 if (GTK_WIDGET_DRAWABLE (widget))
3036 gtk_widget_queue_clear (widget);
3040 /*****************************************
3041 * gtk_widget_set_sensitive:
3045 * boolean value for sensitivity
3048 *****************************************/
3051 gtk_widget_set_sensitive (GtkWidget *widget,
3056 g_return_if_fail (widget != NULL);
3057 g_return_if_fail (GTK_IS_WIDGET (widget));
3059 sensitive = (sensitive != FALSE);
3061 if (sensitive == (GTK_WIDGET_SENSITIVE (widget) != FALSE))
3066 GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
3067 data.state = GTK_WIDGET_SAVED_STATE (widget);
3071 GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
3072 data.state = GTK_WIDGET_STATE (widget);
3074 data.state_restoration = TRUE;
3075 data.use_forall = TRUE;
3078 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
3080 data.parent_sensitive = TRUE;
3082 gtk_widget_propagate_state (widget, &data);
3083 if (GTK_WIDGET_DRAWABLE (widget))
3084 gtk_widget_queue_clear (widget);
3087 /*****************************************
3088 * gtk_widget_set_parent:
3093 *****************************************/
3096 gtk_widget_set_parent (GtkWidget *widget,
3101 g_return_if_fail (widget != NULL);
3102 g_return_if_fail (GTK_IS_WIDGET (widget));
3103 g_return_if_fail (widget->parent == NULL);
3104 g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
3105 g_return_if_fail (parent != NULL);
3106 g_return_if_fail (GTK_IS_WIDGET (parent));
3107 g_return_if_fail (widget != parent);
3109 /* keep this function in sync with gtk_menu_attach_to_widget()
3112 gtk_widget_ref (widget);
3113 gtk_object_sink (GTK_OBJECT (widget));
3114 widget->parent = parent;
3116 if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL)
3117 data.state = GTK_WIDGET_STATE (parent);
3119 data.state = GTK_WIDGET_STATE (widget);
3120 data.state_restoration = FALSE;
3121 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (parent) != FALSE);
3122 data.use_forall = GTK_WIDGET_IS_SENSITIVE (parent) != GTK_WIDGET_IS_SENSITIVE (widget);
3124 gtk_widget_propagate_state (widget, &data);
3126 gtk_widget_set_style_recurse (widget, NULL);
3128 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], NULL);
3131 /*****************************************
3133 * see docs/styles.txt
3134 *****************************************/
3136 gtk_widget_set_style (GtkWidget *widget,
3139 GtkStyle *default_style;
3140 gboolean initial_emission;
3142 g_return_if_fail (widget != NULL);
3143 g_return_if_fail (GTK_IS_WIDGET (widget));
3144 g_return_if_fail (style != NULL);
3146 initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3148 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
3149 GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
3151 default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3154 gtk_style_ref (widget->style);
3155 if (!saved_default_style_key_id)
3156 saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
3157 gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
3160 gtk_widget_set_style_internal (widget, style, initial_emission);
3164 gtk_widget_ensure_style (GtkWidget *widget)
3166 g_return_if_fail (widget != NULL);
3167 g_return_if_fail (GTK_IS_WIDGET (widget));
3169 if (!GTK_WIDGET_USER_STYLE (widget) &&
3170 !GTK_WIDGET_RC_STYLE (widget))
3171 gtk_widget_set_rc_style (widget);
3175 gtk_widget_set_rc_style (GtkWidget *widget)
3177 GtkStyle *saved_style;
3178 GtkStyle *new_style;
3179 gboolean initial_emission;
3181 g_return_if_fail (widget != NULL);
3182 g_return_if_fail (GTK_IS_WIDGET (widget));
3184 initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3186 GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3187 GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
3189 saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3190 new_style = gtk_rc_get_style (widget);
3195 gtk_style_ref (widget->style);
3196 if (!saved_default_style_key_id)
3197 saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
3198 gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
3200 gtk_widget_set_style_internal (widget, new_style, initial_emission);
3206 g_assert (initial_emission == FALSE); /* FIXME: remove this line */
3208 gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3209 gtk_widget_set_style_internal (widget, saved_style, initial_emission);
3210 gtk_style_unref (saved_style);
3214 if (initial_emission)
3215 gtk_widget_set_style_internal (widget, widget->style, TRUE);
3221 gtk_widget_restore_default_style (GtkWidget *widget)
3223 GtkStyle *default_style;
3225 g_return_if_fail (widget != NULL);
3226 g_return_if_fail (GTK_IS_WIDGET (widget));
3228 GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3230 default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3233 gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3234 gtk_widget_set_style_internal (widget, default_style, FALSE);
3235 gtk_style_unref (default_style);
3240 gtk_widget_get_style (GtkWidget *widget)
3242 g_return_val_if_fail (widget != NULL, NULL);
3243 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3245 return widget->style;
3249 gtk_widget_modify_style (GtkWidget *widget,
3252 GtkRcStyle *old_style;
3254 if (!rc_style_key_id)
3255 rc_style_key_id = g_quark_from_static_string (rc_style_key);
3257 old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), rc_style_key_id);
3259 if (style != old_style)
3260 gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3263 (GtkDestroyNotify)gtk_rc_style_unref);
3267 gtk_widget_style_set (GtkWidget *widget,
3268 GtkStyle *previous_style)
3270 if (GTK_WIDGET_REALIZED (widget) &&
3271 !GTK_WIDGET_NO_WINDOW (widget))
3273 gtk_style_set_background (widget->style, widget->window, widget->state);
3274 if (GTK_WIDGET_DRAWABLE (widget))
3275 gdk_window_clear (widget->window);
3280 gtk_widget_set_style_internal (GtkWidget *widget,
3282 gboolean initial_emission)
3284 g_return_if_fail (widget != NULL);
3285 g_return_if_fail (GTK_IS_WIDGET (widget));
3286 g_return_if_fail (style != NULL);
3288 if (widget->style != style)
3290 GtkStyle *previous_style;
3292 if (GTK_WIDGET_REALIZED (widget))
3294 gtk_widget_reset_shapes (widget);
3295 gtk_style_detach (widget->style);
3298 previous_style = widget->style;
3299 widget->style = style;
3300 gtk_style_ref (widget->style);
3302 if (GTK_WIDGET_REALIZED (widget))
3303 widget->style = gtk_style_attach (widget->style, widget->window);
3305 gtk_signal_emit (GTK_OBJECT (widget),
3306 widget_signals[STYLE_SET],
3307 initial_emission ? NULL : previous_style);
3308 gtk_style_unref (previous_style);
3310 if (widget->parent && !initial_emission)
3312 GtkRequisition old_requisition;
3314 old_requisition = widget->requisition;
3315 gtk_widget_size_request (widget, &widget->requisition);
3317 if ((old_requisition.width != widget->requisition.width) ||
3318 (old_requisition.height != widget->requisition.height))
3319 gtk_widget_queue_resize (widget);
3320 else if (GTK_WIDGET_DRAWABLE (widget))
3321 gtk_widget_queue_clear (widget);
3324 else if (initial_emission)
3326 gtk_signal_emit (GTK_OBJECT (widget),
3327 widget_signals[STYLE_SET],
3333 gtk_widget_set_style_recurse (GtkWidget *widget,
3334 gpointer client_data)
3336 if (GTK_WIDGET_RC_STYLE (widget))
3337 gtk_widget_set_rc_style (widget);
3339 if (GTK_IS_CONTAINER (widget))
3340 gtk_container_forall (GTK_CONTAINER (widget),
3341 gtk_widget_set_style_recurse,
3346 gtk_widget_reset_rc_styles (GtkWidget *widget)
3348 g_return_if_fail (widget != NULL);
3349 g_return_if_fail (GTK_IS_WIDGET (widget));
3351 gtk_widget_set_style_recurse (widget, NULL);
3355 gtk_widget_set_default_style (GtkStyle *style)
3357 if (style != gtk_default_style)
3359 if (gtk_default_style)
3360 gtk_style_unref (gtk_default_style);
3361 gtk_default_style = style;
3362 if (gtk_default_style)
3363 gtk_style_ref (gtk_default_style);
3368 gtk_widget_get_default_style (void)
3370 if (!gtk_default_style)
3372 gtk_default_style = gtk_style_new ();
3373 gtk_style_ref (gtk_default_style);
3376 return gtk_default_style;
3380 gtk_widget_push_style (GtkStyle *style)
3382 g_return_if_fail (style != NULL);
3384 gtk_style_ref (style);
3385 style_stack = g_slist_prepend (style_stack, style);
3389 gtk_widget_peek_style (void)
3392 return (GtkStyle*) style_stack->data;
3394 return gtk_widget_get_default_style ();
3398 gtk_widget_pop_style (void)
3405 style_stack = style_stack->next;
3406 gtk_style_unref ((GtkStyle*) tmp->data);
3407 g_slist_free_1 (tmp);
3411 /*************************************************************
3412 * gtk_widget_set_parent_window:
3413 * Set a non default parent window for widget
3420 *************************************************************/
3423 gtk_widget_set_parent_window (GtkWidget *widget,
3424 GdkWindow *parent_window)
3426 GdkWindow *old_parent_window;
3428 g_return_if_fail (widget != NULL);
3429 g_return_if_fail (GTK_IS_WIDGET (widget));
3431 old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3432 parent_window_key_id);
3434 if (parent_window != old_parent_window)
3436 if (!parent_window_key_id)
3437 parent_window_key_id = g_quark_from_static_string (parent_window_key);
3438 gtk_object_set_data_by_id (GTK_OBJECT (widget), parent_window_key_id,
3440 if (old_parent_window)
3441 gdk_window_unref (old_parent_window);
3443 gdk_window_ref (parent_window);
3447 /*************************************************************
3448 * gtk_widget_get_parent_window:
3449 * Get widget's parent window
3456 *************************************************************/
3459 gtk_widget_get_parent_window (GtkWidget *widget)
3461 GdkWindow *parent_window;
3463 g_return_val_if_fail (widget != NULL, NULL);
3464 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3465 g_return_val_if_fail (widget->parent != NULL, NULL);
3467 parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3468 parent_window_key_id);
3470 return (parent_window != NULL) ? parent_window : widget->parent->window;
3473 /*****************************************
3474 * gtk_widget_set_uposition:
3479 *****************************************/
3482 gtk_widget_set_uposition (GtkWidget *widget,
3486 GtkWidgetAuxInfo *aux_info;
3488 g_return_if_fail (widget != NULL);
3489 g_return_if_fail (GTK_IS_WIDGET (widget));
3491 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3494 if (!aux_info_key_id)
3495 aux_info_key_id = g_quark_from_static_string (aux_info_key);
3496 aux_info = gtk_widget_aux_info_new ();
3497 gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3505 if (GTK_WIDGET_REALIZED (widget) && GTK_IS_WINDOW (widget) &&
3506 (aux_info->x != -1) && (aux_info->y != -1))
3508 gdk_window_set_hints (widget->window, aux_info->x, aux_info->y, 0, 0, 0, 0, GDK_HINT_POS);
3509 gdk_window_move (widget->window, aux_info->x, aux_info->y);
3512 if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
3513 gtk_widget_size_allocate (widget, &widget->allocation);
3516 /*****************************************
3517 * gtk_widget_set_usize:
3522 *****************************************/
3525 gtk_widget_set_usize (GtkWidget *widget,
3529 GtkWidgetAuxInfo *aux_info;
3531 g_return_if_fail (widget != NULL);
3532 g_return_if_fail (GTK_IS_WIDGET (widget));
3534 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3537 if (!aux_info_key_id)
3538 aux_info_key_id = g_quark_from_static_string (aux_info_key);
3539 aux_info = gtk_widget_aux_info_new ();
3540 gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3544 aux_info->width = width;
3546 aux_info->height = height;
3548 if (GTK_WIDGET_VISIBLE (widget))
3549 gtk_widget_queue_resize (widget);
3552 /*****************************************
3553 * gtk_widget_set_events:
3558 *****************************************/
3561 gtk_widget_set_events (GtkWidget *widget,
3566 g_return_if_fail (widget != NULL);
3567 g_return_if_fail (GTK_IS_WIDGET (widget));
3568 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3569 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
3571 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3576 eventp = g_new (gint, 1);
3580 event_key_id = g_quark_from_static_string (event_key);
3581 gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3586 gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3590 /*****************************************
3591 * gtk_widget_add_events:
3596 *****************************************/
3599 gtk_widget_add_events (GtkWidget *widget,
3604 g_return_if_fail (widget != NULL);
3605 g_return_if_fail (GTK_IS_WIDGET (widget));
3606 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3608 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3614 eventp = g_new (gint, 1);
3620 event_key_id = g_quark_from_static_string (event_key);
3621 gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3626 gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3629 if (GTK_WIDGET_REALIZED (widget))
3631 gdk_window_set_events (widget->window,
3632 gdk_window_get_events (widget->window) | events);
3636 /*****************************************
3637 * gtk_widget_set_extension_events:
3642 *****************************************/
3645 gtk_widget_set_extension_events (GtkWidget *widget,
3646 GdkExtensionMode mode)
3648 GdkExtensionMode *modep;
3650 g_return_if_fail (widget != NULL);
3651 g_return_if_fail (GTK_IS_WIDGET (widget));
3653 modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3656 modep = g_new (GdkExtensionMode, 1);
3659 if (!extension_event_key_id)
3660 extension_event_key_id = g_quark_from_static_string (extension_event_key);
3661 gtk_object_set_data_by_id (GTK_OBJECT (widget), extension_event_key_id, modep);
3664 /*****************************************
3665 * gtk_widget_get_toplevel:
3670 *****************************************/
3673 gtk_widget_get_toplevel (GtkWidget *widget)
3675 g_return_val_if_fail (widget != NULL, NULL);
3676 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3678 while (widget->parent)
3679 widget = widget->parent;
3684 /*****************************************
3685 * gtk_widget_get_ancestor:
3690 *****************************************/
3693 gtk_widget_get_ancestor (GtkWidget *widget,
3694 GtkType widget_type)
3696 g_return_val_if_fail (widget != NULL, NULL);
3697 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3699 while (widget && !gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type))
3700 widget = widget->parent;
3702 if (!(widget && gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type)))
3708 /*****************************************
3709 * gtk_widget_get_colormap:
3714 *****************************************/
3717 gtk_widget_get_colormap (GtkWidget *widget)
3719 GdkColormap *colormap;
3721 g_return_val_if_fail (widget != NULL, NULL);
3722 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3726 colormap = gdk_window_get_colormap (widget->window);
3727 /* If window was destroyed previously, we'll get NULL here */
3732 colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
3736 return gtk_widget_get_default_colormap ();
3739 /*****************************************
3740 * gtk_widget_get_visual:
3745 *****************************************/
3748 gtk_widget_get_visual (GtkWidget *widget)
3752 g_return_val_if_fail (widget != NULL, NULL);
3753 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3757 visual = gdk_window_get_visual (widget->window);
3758 /* If window was destroyed previously, we'll get NULL here */
3763 visual = gtk_object_get_data (GTK_OBJECT (widget), visual_key);
3767 return gtk_widget_get_default_visual ();
3770 /*****************************************
3771 * gtk_widget_get_events:
3776 *****************************************/
3779 gtk_widget_get_events (GtkWidget *widget)
3783 g_return_val_if_fail (widget != NULL, 0);
3784 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3786 events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3793 /*****************************************
3794 * gtk_widget_get_extension_events:
3799 *****************************************/
3802 gtk_widget_get_extension_events (GtkWidget *widget)
3804 GdkExtensionMode *mode;
3806 g_return_val_if_fail (widget != NULL, 0);
3807 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3809 mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3816 /*****************************************
3817 * gtk_widget_get_pointer:
3822 *****************************************/
3825 gtk_widget_get_pointer (GtkWidget *widget,
3829 g_return_if_fail (widget != NULL);
3830 g_return_if_fail (GTK_IS_WIDGET (widget));
3837 if (GTK_WIDGET_REALIZED (widget))
3839 gdk_window_get_pointer (widget->window, x, y, NULL);
3841 if (GTK_WIDGET_NO_WINDOW (widget))
3844 *x -= widget->allocation.x;
3846 *y -= widget->allocation.y;
3851 /*****************************************
3852 * gtk_widget_is_ancestor:
3857 *****************************************/
3860 gtk_widget_is_ancestor (GtkWidget *widget,
3861 GtkWidget *ancestor)
3863 g_return_val_if_fail (widget != NULL, FALSE);
3864 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3865 g_return_val_if_fail (ancestor != NULL, FALSE);
3869 if (widget->parent == ancestor)
3871 widget = widget->parent;
3877 static GQuark quark_composite_name = 0;
3880 gtk_widget_set_composite_name (GtkWidget *widget,
3883 g_return_if_fail (widget != NULL);
3884 g_return_if_fail (GTK_IS_WIDGET (widget));
3885 g_return_if_fail (GTK_WIDGET_COMPOSITE_CHILD (widget));
3886 g_return_if_fail (name != NULL);
3888 if (!quark_composite_name)
3889 quark_composite_name = g_quark_from_static_string ("gtk-composite-name");
3891 gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3892 quark_composite_name,
3898 gtk_widget_get_composite_name (GtkWidget *widget)
3900 g_return_val_if_fail (widget != NULL, NULL);
3901 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3903 if (GTK_WIDGET_COMPOSITE_CHILD (widget) && widget->parent)
3904 return gtk_container_child_composite_name (GTK_CONTAINER (widget->parent),
3911 gtk_widget_push_composite_child (void)
3913 composite_child_stack++;
3917 gtk_widget_pop_composite_child (void)
3919 if (composite_child_stack)
3920 composite_child_stack--;
3923 /*****************************************
3924 * gtk_widget_push_colormap:
3929 *****************************************/
3932 gtk_widget_push_colormap (GdkColormap *cmap)
3934 g_return_if_fail (cmap != NULL);
3936 colormap_stack = g_slist_prepend (colormap_stack, cmap);
3939 /*****************************************
3940 * gtk_widget_push_visual:
3945 *****************************************/
3948 gtk_widget_push_visual (GdkVisual *visual)
3950 g_return_if_fail (visual != NULL);
3952 visual_stack = g_slist_prepend (visual_stack, visual);
3955 /*****************************************
3956 * gtk_widget_pop_colormap:
3961 *****************************************/
3964 gtk_widget_pop_colormap (void)
3970 tmp = colormap_stack;
3971 colormap_stack = colormap_stack->next;
3972 g_slist_free_1 (tmp);
3976 /*****************************************
3977 * gtk_widget_pop_visual:
3982 *****************************************/
3985 gtk_widget_pop_visual (void)
3992 visual_stack = visual_stack->next;
3993 g_slist_free_1 (tmp);
3997 /*****************************************
3998 * gtk_widget_set_default_colormap:
4003 *****************************************/
4006 gtk_widget_set_default_colormap (GdkColormap *colormap)
4008 if (default_colormap != colormap)
4010 if (default_colormap)
4011 gdk_colormap_unref (default_colormap);
4012 default_colormap = colormap;
4013 if (default_colormap)
4014 gdk_colormap_ref (default_colormap);
4018 /*****************************************
4019 * gtk_widget_set_default_visual:
4024 *****************************************/
4027 gtk_widget_set_default_visual (GdkVisual *visual)
4029 default_visual = visual;
4032 /*****************************************
4033 * gtk_widget_get_default_colormap:
4038 *****************************************/
4041 gtk_widget_get_default_colormap (void)
4043 if (!default_colormap)
4044 default_colormap = gdk_colormap_get_system ();
4046 return default_colormap;
4049 /*****************************************
4050 * gtk_widget_get_default_visual:
4055 *****************************************/
4058 gtk_widget_get_default_visual (void)
4060 if (!default_visual)
4061 default_visual = gdk_visual_get_system ();
4063 return default_visual;
4067 gtk_widget_shutdown (GtkObject *object)
4071 /* gtk_object_destroy() will already hold a refcount on object
4073 widget = GTK_WIDGET (object);
4076 gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
4078 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4079 if (GTK_WIDGET_REALIZED (widget))
4080 gtk_widget_unrealize (widget);
4082 parent_class->shutdown (object);
4086 gtk_widget_real_destroy (GtkObject *object)
4089 GtkStyle *saved_style;
4091 /* gtk_object_destroy() will already hold a refcount on object
4093 widget = GTK_WIDGET (object);
4095 gtk_grab_remove (widget);
4096 gtk_selection_remove_all (widget);
4098 saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id);
4101 gtk_style_unref (saved_style);
4102 gtk_object_remove_data_by_id (object, saved_default_style_key_id);
4105 gtk_style_unref (widget->style);
4106 widget->style = NULL;
4108 parent_class->destroy (object);
4112 gtk_widget_finalize (GtkObject *object)
4115 GtkWidgetAuxInfo *aux_info;
4117 GdkExtensionMode *mode;
4119 widget = GTK_WIDGET (object);
4122 g_free (widget->name);
4124 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
4126 gtk_widget_aux_info_destroy (aux_info);
4128 events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
4132 mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
4136 parent_class->finalize (object);
4139 /*****************************************
4140 * gtk_widget_real_show:
4145 *****************************************/
4148 gtk_widget_real_show (GtkWidget *widget)
4150 g_return_if_fail (widget != NULL);
4151 g_return_if_fail (GTK_IS_WIDGET (widget));
4153 if (!GTK_WIDGET_VISIBLE (widget))
4155 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4159 gtk_widget_queue_resize (widget->parent);
4161 if (GTK_WIDGET_MAPPED (widget->parent))
4162 gtk_widget_map (widget);
4167 /*****************************************
4168 * gtk_widget_real_hide:
4173 *****************************************/
4176 gtk_widget_real_hide (GtkWidget *widget)
4178 g_return_if_fail (widget != NULL);
4179 g_return_if_fail (GTK_IS_WIDGET (widget));
4181 if (GTK_WIDGET_VISIBLE (widget))
4183 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4185 if (GTK_WIDGET_MAPPED (widget))
4186 gtk_widget_unmap (widget);
4189 gtk_widget_queue_resize (widget->parent);
4193 /*****************************************
4194 * gtk_widget_real_map:
4199 *****************************************/
4202 gtk_widget_real_map (GtkWidget *widget)
4204 g_return_if_fail (widget != NULL);
4205 g_return_if_fail (GTK_IS_WIDGET (widget));
4207 if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_MAPPED (widget))
4209 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4211 if (!GTK_WIDGET_NO_WINDOW (widget))
4212 gdk_window_show (widget->window);
4214 gtk_widget_queue_draw (widget);
4218 /*****************************************
4219 * gtk_widget_real_unmap:
4224 *****************************************/
4227 gtk_widget_real_unmap (GtkWidget *widget)
4229 g_return_if_fail (widget != NULL);
4230 g_return_if_fail (GTK_IS_WIDGET (widget));
4232 if (GTK_WIDGET_MAPPED (widget))
4234 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4236 if (GTK_WIDGET_NO_WINDOW (widget))
4237 gtk_widget_queue_clear (widget);
4239 gdk_window_hide (widget->window);
4243 /*****************************************
4244 * gtk_widget_real_realize:
4249 *****************************************/
4252 gtk_widget_real_realize (GtkWidget *widget)
4254 g_return_if_fail (widget != NULL);
4255 g_return_if_fail (GTK_IS_WIDGET (widget));
4256 g_return_if_fail (GTK_WIDGET_NO_WINDOW (widget));
4258 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4261 widget->window = gtk_widget_get_parent_window (widget);
4262 gdk_window_ref (widget->window);
4264 widget->style = gtk_style_attach (widget->style, widget->window);
4267 /*****************************************
4268 * gtk_widget_real_unrealize:
4273 *****************************************/
4276 gtk_widget_real_unrealize (GtkWidget *widget)
4278 g_return_if_fail (widget != NULL);
4279 g_return_if_fail (GTK_IS_WIDGET (widget));
4281 if (GTK_WIDGET_MAPPED (widget))
4282 gtk_widget_real_unmap (widget);
4284 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4286 /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT(widget)->klass->type));
4289 /* We must do unrealize child widget BEFORE container widget.
4290 * gdk_window_destroy() destroys specified xwindow and it's sub-xwindows.
4291 * So, unrealizing container widget bofore it's children causes the problem
4292 * (for example, gdk_ic_destroy () with destroyed window causes crash. )
4295 if (GTK_IS_CONTAINER (widget))
4296 gtk_container_foreach (GTK_CONTAINER (widget),
4297 (GtkCallback) gtk_widget_unrealize,
4300 gtk_style_detach (widget->style);
4301 if (!GTK_WIDGET_NO_WINDOW (widget))
4303 gdk_window_set_user_data (widget->window, NULL);
4304 gdk_window_destroy (widget->window);
4305 widget->window = NULL;
4309 gdk_window_unref (widget->window);
4310 widget->window = NULL;
4313 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
4316 /*****************************************
4317 * gtk_widget_real_draw:
4322 *****************************************/
4325 gtk_widget_real_draw (GtkWidget *widget,
4328 GdkEventExpose event;
4330 g_return_if_fail (widget != NULL);
4331 g_return_if_fail (GTK_IS_WIDGET (widget));
4332 g_return_if_fail (area != NULL);
4334 if (GTK_WIDGET_DRAWABLE (widget))
4336 event.type = GDK_EXPOSE;
4337 event.send_event = TRUE;
4338 event.window = widget->window;
4342 gdk_window_ref (event.window);
4343 gtk_widget_event (widget, (GdkEvent*) &event);
4344 gdk_window_unref (event.window);
4349 gtk_widget_real_size_request (GtkWidget *widget,
4350 GtkRequisition *requisition)
4352 g_return_if_fail (widget != NULL);
4353 g_return_if_fail (GTK_IS_WIDGET (widget));
4355 requisition->width = widget->requisition.width;
4356 requisition->height = widget->requisition.height;
4360 gtk_widget_real_size_allocate (GtkWidget *widget,
4361 GtkAllocation *allocation)
4363 g_return_if_fail (widget != NULL);
4364 g_return_if_fail (GTK_IS_WIDGET (widget));
4366 if (GTK_WIDGET_NO_WINDOW (widget) &&
4367 GTK_WIDGET_MAPPED (widget) &&
4368 ((widget->allocation.x != allocation->x) ||
4369 (widget->allocation.y != allocation->y) ||
4370 (widget->allocation.width != allocation->width) ||
4371 (widget->allocation.height != allocation->height)) &&
4372 (widget->allocation.width != 0) &&
4373 (widget->allocation.height != 0))
4374 gtk_widget_queue_clear (widget);
4376 widget->allocation = *allocation;
4378 if (GTK_WIDGET_REALIZED (widget) &&
4379 !GTK_WIDGET_NO_WINDOW (widget))
4381 gdk_window_move_resize (widget->window,
4382 allocation->x, allocation->y,
4383 allocation->width, allocation->height);
4387 /*****************************************
4388 * gtk_widget_peek_colormap:
4393 *****************************************/
4396 gtk_widget_peek_colormap (void)
4399 return (GdkColormap*) colormap_stack->data;
4400 return gtk_widget_get_default_colormap ();
4403 /*****************************************
4404 * gtk_widget_peek_visual:
4409 *****************************************/
4412 gtk_widget_peek_visual (void)
4415 return (GdkVisual*) visual_stack->data;
4416 return gtk_widget_get_default_visual ();
4420 gtk_widget_propagate_state (GtkWidget *widget,
4425 /* don't call this function with state==GTK_STATE_INSENSITIVE,
4426 * parent_sensitive==TRUE on a sensitive widget
4429 old_state = GTK_WIDGET_STATE (widget);
4431 if (data->parent_sensitive)
4433 GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4435 if (GTK_WIDGET_IS_SENSITIVE (widget))
4437 if (data->state_restoration)
4438 GTK_WIDGET_STATE (widget) = GTK_WIDGET_SAVED_STATE (widget);
4440 GTK_WIDGET_STATE (widget) = data->state;
4444 GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4445 if (!data->state_restoration &&
4446 data->state != GTK_STATE_INSENSITIVE)
4447 GTK_WIDGET_SAVED_STATE (widget) = data->state;
4452 GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4453 if (!data->state_restoration)
4455 if (data->state != GTK_STATE_INSENSITIVE)
4456 GTK_WIDGET_SAVED_STATE (widget) = data->state;
4458 else if (GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE)
4459 GTK_WIDGET_SAVED_STATE (widget) = GTK_WIDGET_STATE (widget);
4460 GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4463 if (GTK_WIDGET_HAS_FOCUS (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
4467 window = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
4469 gtk_window_set_focus (GTK_WINDOW (window), NULL);
4472 if (old_state != GTK_WIDGET_STATE (widget))
4474 gtk_widget_ref (widget);
4475 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state);
4477 if (GTK_IS_CONTAINER (widget))
4479 data->parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget) != FALSE);
4480 data->state = GTK_WIDGET_STATE (widget);
4481 if (data->use_forall)
4482 gtk_container_forall (GTK_CONTAINER (widget),
4483 (GtkCallback) gtk_widget_propagate_state,
4486 gtk_container_foreach (GTK_CONTAINER (widget),
4487 (GtkCallback) gtk_widget_propagate_state,
4490 gtk_widget_unref (widget);
4494 /*****************************************
4495 * gtk_widget_aux_info_new:
4500 *****************************************/
4502 static GtkWidgetAuxInfo*
4503 gtk_widget_aux_info_new (void)
4505 GtkWidgetAuxInfo *aux_info;
4507 if (!aux_info_mem_chunk)
4508 aux_info_mem_chunk = g_mem_chunk_new ("widget aux info mem chunk",
4509 sizeof (GtkWidgetAuxInfo),
4510 1024, G_ALLOC_AND_FREE);
4512 aux_info = g_chunk_new (GtkWidgetAuxInfo, aux_info_mem_chunk);
4516 aux_info->width = 0;
4517 aux_info->height = 0;
4522 /*****************************************
4523 * gtk_widget_aux_info_destroy:
4528 *****************************************/
4531 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
4533 g_return_if_fail (aux_info != NULL);
4535 g_mem_chunk_free (aux_info_mem_chunk, aux_info);
4538 /*****************************************
4539 * gtk_widget_shape_combine_mask:
4540 * set a shape for this widgets' gdk window, this allows for
4541 * transparent windows etc., see gdk_window_shape_combine_mask
4542 * for more information
4547 *****************************************/
4549 gtk_widget_shape_combine_mask (GtkWidget *widget,
4550 GdkBitmap *shape_mask,
4554 GtkWidgetShapeInfo* shape_info;
4556 g_return_if_fail (widget != NULL);
4557 g_return_if_fail (GTK_IS_WIDGET (widget));
4558 /* set_shape doesn't work on widgets without gdk window */
4559 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
4563 GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4566 gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
4568 shape_info = gtk_object_get_data (GTK_OBJECT (widget), shape_info_key);
4569 gtk_object_remove_data (GTK_OBJECT (widget), shape_info_key);
4570 g_free (shape_info);
4574 GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4576 shape_info = gtk_object_get_data (GTK_OBJECT (widget), shape_info_key);
4579 shape_info = g_new (GtkWidgetShapeInfo, 1);
4580 gtk_object_set_data (GTK_OBJECT (widget), shape_info_key, shape_info);
4582 shape_info->shape_mask = shape_mask;
4583 shape_info->offset_x = offset_x;
4584 shape_info->offset_y = offset_y;
4586 /* set shape if widget has a gdk window allready.
4587 * otherwise the shape is scheduled to be set by gtk_widget_realize.
4590 gdk_window_shape_combine_mask (widget->window, shape_mask,
4591 offset_x, offset_y);
4596 gtk_reset_shapes_recurse (GtkWidget *widget,
4599 GdkWindowPrivate *private;
4603 private = (GdkWindowPrivate*) window;
4605 if (private->destroyed)
4607 gdk_window_get_user_data (window, &data);
4611 gdk_window_shape_combine_mask (window, NULL, 0, 0);
4612 for (list = private->children; list; list = list->next)
4613 gtk_reset_shapes_recurse (widget, list->data);
4617 gtk_widget_reset_shapes (GtkWidget *widget)
4619 g_return_if_fail (widget != NULL);
4620 g_return_if_fail (GTK_IS_WIDGET (widget));
4621 g_return_if_fail (GTK_WIDGET_REALIZED (widget));
4623 if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
4624 gtk_reset_shapes_recurse (widget, widget->window);
4628 gtk_widget_ref (GtkWidget *widget)
4630 g_return_if_fail (widget != NULL);
4631 g_return_if_fail (GTK_IS_WIDGET (widget));
4633 gtk_object_ref ((GtkObject*) widget);
4637 gtk_widget_unref (GtkWidget *widget)
4639 g_return_if_fail (widget != NULL);
4640 g_return_if_fail (GTK_IS_WIDGET (widget));
4642 gtk_object_unref ((GtkObject*) widget);
4646 gtk_widget_path (GtkWidget *widget,
4647 guint *path_length_p,
4649 gchar **path_reversed_p)
4651 static gchar *rev_path = NULL;
4652 static guint path_len = 0;
4655 g_return_if_fail (widget != NULL);
4656 g_return_if_fail (GTK_IS_WIDGET (widget));
4665 string = gtk_widget_get_name (widget);
4666 l = strlen (string);
4667 while (path_len <= len + l + 1)
4669 path_len += INIT_PATH_SIZE;
4670 rev_path = g_realloc (rev_path, path_len);
4678 widget = widget->parent;
4681 rev_path[len++] = '.';
4683 rev_path[len++] = 0;
4688 *path_length_p = len - 1;
4689 if (path_reversed_p)
4690 *path_reversed_p = g_strdup (rev_path);
4693 *path_p = g_strdup (rev_path);
4694 g_strreverse (*path_p);
4699 gtk_widget_class_path (GtkWidget *widget,
4700 guint *path_length_p,
4702 gchar **path_reversed_p)
4704 static gchar *rev_path = NULL;
4705 static guint path_len = 0;
4708 g_return_if_fail (widget != NULL);
4709 g_return_if_fail (GTK_IS_WIDGET (widget));
4718 string = gtk_type_name (GTK_WIDGET_TYPE (widget));
4719 l = strlen (string);
4720 while (path_len <= len + l + 1)
4722 path_len += INIT_PATH_SIZE;
4723 rev_path = g_realloc (rev_path, path_len);
4731 widget = widget->parent;
4734 rev_path[len++] = '.';
4736 rev_path[len++] = 0;
4741 *path_length_p = len - 1;
4742 if (path_reversed_p)
4743 *path_reversed_p = g_strdup (rev_path);
4746 *path_p = g_strdup (rev_path);
4747 g_strreverse (*path_p);