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)
71 PROPERTY_NOTIFY_EVENT,
72 SELECTION_CLEAR_EVENT,
73 SELECTION_REQUEST_EVENT,
74 SELECTION_NOTIFY_EVENT,
89 VISIBILITY_NOTIFY_EVENT,
114 typedef struct _GtkStateData GtkStateData;
119 guint state_restoration : 1;
120 guint parent_sensitive : 1;
121 guint use_forall : 1;
124 static void gtk_widget_class_init (GtkWidgetClass *klass);
125 static void gtk_widget_init (GtkWidget *widget);
126 static void gtk_widget_set_arg (GtkObject *object,
129 static void gtk_widget_get_arg (GtkObject *object,
132 static void gtk_widget_shutdown (GtkObject *object);
133 static void gtk_widget_real_destroy (GtkObject *object);
134 static void gtk_widget_finalize (GtkObject *object);
135 static void gtk_widget_real_show (GtkWidget *widget);
136 static void gtk_widget_real_hide (GtkWidget *widget);
137 static void gtk_widget_real_map (GtkWidget *widget);
138 static void gtk_widget_real_unmap (GtkWidget *widget);
139 static void gtk_widget_real_realize (GtkWidget *widget);
140 static void gtk_widget_real_unrealize (GtkWidget *widget);
141 static void gtk_widget_real_draw (GtkWidget *widget,
143 static void gtk_widget_real_size_request (GtkWidget *widget,
144 GtkRequisition *requisition);
145 static void gtk_widget_real_size_allocate (GtkWidget *widget,
146 GtkAllocation *allocation);
147 static gint gtk_widget_real_key_press_event (GtkWidget *widget,
149 static gint gtk_widget_real_key_release_event (GtkWidget *widget,
151 static void gtk_widget_style_set (GtkWidget *widget,
152 GtkStyle *previous_style);
154 static void gtk_widget_redraw_queue_remove (GtkWidget *widget);
157 static GdkColormap* gtk_widget_peek_colormap (void);
158 static GdkVisual* gtk_widget_peek_visual (void);
159 static GtkStyle* gtk_widget_peek_style (void);
161 static void gtk_widget_reparent_container_child (GtkWidget *widget,
162 gpointer client_data);
163 static void gtk_widget_propagate_state (GtkWidget *widget,
165 static void gtk_widget_draw_children_recurse (GtkWidget *widget,
166 gpointer client_data);
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 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[EVENT] =
393 gtk_signal_new ("event",
396 GTK_SIGNAL_OFFSET (GtkWidgetClass, event),
397 gtk_marshal_BOOL__POINTER,
400 widget_signals[BUTTON_PRESS_EVENT] =
401 gtk_signal_new ("button_press_event",
404 GTK_SIGNAL_OFFSET (GtkWidgetClass, button_press_event),
405 gtk_marshal_BOOL__POINTER,
408 widget_signals[BUTTON_RELEASE_EVENT] =
409 gtk_signal_new ("button_release_event",
412 GTK_SIGNAL_OFFSET (GtkWidgetClass, button_release_event),
413 gtk_marshal_BOOL__POINTER,
416 widget_signals[MOTION_NOTIFY_EVENT] =
417 gtk_signal_new ("motion_notify_event",
420 GTK_SIGNAL_OFFSET (GtkWidgetClass, motion_notify_event),
421 gtk_marshal_BOOL__POINTER,
424 widget_signals[DELETE_EVENT] =
425 gtk_signal_new ("delete_event",
428 GTK_SIGNAL_OFFSET (GtkWidgetClass, delete_event),
429 gtk_marshal_BOOL__POINTER,
432 widget_signals[DESTROY_EVENT] =
433 gtk_signal_new ("destroy_event",
436 GTK_SIGNAL_OFFSET (GtkWidgetClass, destroy_event),
437 gtk_marshal_BOOL__POINTER,
440 widget_signals[EXPOSE_EVENT] =
441 gtk_signal_new ("expose_event",
444 GTK_SIGNAL_OFFSET (GtkWidgetClass, expose_event),
445 gtk_marshal_BOOL__POINTER,
448 widget_signals[KEY_PRESS_EVENT] =
449 gtk_signal_new ("key_press_event",
452 GTK_SIGNAL_OFFSET (GtkWidgetClass, key_press_event),
453 gtk_marshal_BOOL__POINTER,
456 widget_signals[KEY_RELEASE_EVENT] =
457 gtk_signal_new ("key_release_event",
460 GTK_SIGNAL_OFFSET (GtkWidgetClass, key_release_event),
461 gtk_marshal_BOOL__POINTER,
464 widget_signals[ENTER_NOTIFY_EVENT] =
465 gtk_signal_new ("enter_notify_event",
468 GTK_SIGNAL_OFFSET (GtkWidgetClass, enter_notify_event),
469 gtk_marshal_BOOL__POINTER,
472 widget_signals[LEAVE_NOTIFY_EVENT] =
473 gtk_signal_new ("leave_notify_event",
476 GTK_SIGNAL_OFFSET (GtkWidgetClass, leave_notify_event),
477 gtk_marshal_BOOL__POINTER,
480 widget_signals[CONFIGURE_EVENT] =
481 gtk_signal_new ("configure_event",
484 GTK_SIGNAL_OFFSET (GtkWidgetClass, configure_event),
485 gtk_marshal_BOOL__POINTER,
488 widget_signals[FOCUS_IN_EVENT] =
489 gtk_signal_new ("focus_in_event",
492 GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_in_event),
493 gtk_marshal_BOOL__POINTER,
496 widget_signals[FOCUS_OUT_EVENT] =
497 gtk_signal_new ("focus_out_event",
500 GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_out_event),
501 gtk_marshal_BOOL__POINTER,
504 widget_signals[MAP_EVENT] =
505 gtk_signal_new ("map_event",
508 GTK_SIGNAL_OFFSET (GtkWidgetClass, map_event),
509 gtk_marshal_BOOL__POINTER,
512 widget_signals[UNMAP_EVENT] =
513 gtk_signal_new ("unmap_event",
516 GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap_event),
517 gtk_marshal_BOOL__POINTER,
520 widget_signals[PROPERTY_NOTIFY_EVENT] =
521 gtk_signal_new ("property_notify_event",
524 GTK_SIGNAL_OFFSET (GtkWidgetClass, property_notify_event),
525 gtk_marshal_BOOL__POINTER,
528 widget_signals[SELECTION_CLEAR_EVENT] =
529 gtk_signal_new ("selection_clear_event",
532 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_clear_event),
533 gtk_marshal_BOOL__POINTER,
536 widget_signals[SELECTION_REQUEST_EVENT] =
537 gtk_signal_new ("selection_request_event",
540 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_request_event),
541 gtk_marshal_BOOL__POINTER,
544 widget_signals[SELECTION_NOTIFY_EVENT] =
545 gtk_signal_new ("selection_notify_event",
548 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_notify_event),
549 gtk_marshal_BOOL__POINTER,
552 widget_signals[SELECTION_RECEIVED] =
553 gtk_signal_new ("selection_received",
556 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_received),
557 gtk_marshal_NONE__POINTER_UINT,
559 GTK_TYPE_SELECTION_DATA,
561 widget_signals[SELECTION_GET] =
562 gtk_signal_new ("selection_get",
565 GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_get),
566 gtk_marshal_NONE__POINTER_UINT_UINT,
568 GTK_TYPE_SELECTION_DATA,
571 widget_signals[PROXIMITY_IN_EVENT] =
572 gtk_signal_new ("proximity_in_event",
575 GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_in_event),
576 gtk_marshal_BOOL__POINTER,
579 widget_signals[PROXIMITY_OUT_EVENT] =
580 gtk_signal_new ("proximity_out_event",
583 GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_out_event),
584 gtk_marshal_BOOL__POINTER,
587 widget_signals[DRAG_LEAVE] =
588 gtk_signal_new ("drag_leave",
591 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_leave),
592 gtk_marshal_NONE__POINTER_UINT,
594 GTK_TYPE_GDK_DRAG_CONTEXT,
596 widget_signals[DRAG_BEGIN] =
597 gtk_signal_new ("drag_begin",
600 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin),
601 gtk_marshal_NONE__POINTER,
603 GTK_TYPE_GDK_DRAG_CONTEXT);
604 widget_signals[DRAG_END] =
605 gtk_signal_new ("drag_end",
608 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_end),
609 gtk_marshal_NONE__POINTER,
611 GTK_TYPE_GDK_DRAG_CONTEXT);
612 widget_signals[DRAG_DATA_DELETE] =
613 gtk_signal_new ("drag_data_delete",
616 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_delete),
617 gtk_marshal_NONE__POINTER,
619 GTK_TYPE_GDK_DRAG_CONTEXT);
620 widget_signals[DRAG_MOTION] =
621 gtk_signal_new ("drag_motion",
624 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_motion),
625 gtk_marshal_BOOL__POINTER_INT_INT_UINT,
627 GTK_TYPE_GDK_DRAG_CONTEXT,
631 widget_signals[DRAG_DROP] =
632 gtk_signal_new ("drag_drop",
635 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_drop),
636 gtk_marshal_BOOL__POINTER_INT_INT_UINT,
638 GTK_TYPE_GDK_DRAG_CONTEXT,
642 widget_signals[DRAG_DATA_GET] =
643 gtk_signal_new ("drag_data_get",
646 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_get),
647 gtk_marshal_NONE__POINTER_POINTER_UINT_UINT,
649 GTK_TYPE_GDK_DRAG_CONTEXT,
650 GTK_TYPE_SELECTION_DATA,
653 widget_signals[DRAG_DATA_RECEIVED] =
654 gtk_signal_new ("drag_data_received",
657 GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_data_received),
658 gtk_marshal_NONE__POINTER_INT_INT_POINTER_UINT_UINT,
660 GTK_TYPE_GDK_DRAG_CONTEXT,
663 GTK_TYPE_SELECTION_DATA,
666 widget_signals[VISIBILITY_NOTIFY_EVENT] =
667 gtk_signal_new ("visibility_notify_event",
670 GTK_SIGNAL_OFFSET (GtkWidgetClass, visibility_notify_event),
671 gtk_marshal_BOOL__POINTER,
674 widget_signals[CLIENT_EVENT] =
675 gtk_signal_new ("client_event",
678 GTK_SIGNAL_OFFSET (GtkWidgetClass, client_event),
679 gtk_marshal_BOOL__POINTER,
682 widget_signals[NO_EXPOSE_EVENT] =
683 gtk_signal_new ("no_expose_event",
686 GTK_SIGNAL_OFFSET (GtkWidgetClass, no_expose_event),
687 gtk_marshal_BOOL__POINTER,
690 widget_signals[DEBUG_MSG] =
691 gtk_signal_new ("debug_msg",
692 GTK_RUN_LAST | GTK_RUN_ACTION,
694 GTK_SIGNAL_OFFSET (GtkWidgetClass, debug_msg),
695 gtk_marshal_NONE__STRING,
699 gtk_object_class_add_signals (object_class, widget_signals, LAST_SIGNAL);
701 object_class->set_arg = gtk_widget_set_arg;
702 object_class->get_arg = gtk_widget_get_arg;
703 object_class->shutdown = gtk_widget_shutdown;
704 object_class->destroy = gtk_widget_real_destroy;
705 object_class->finalize = gtk_widget_finalize;
707 klass->activate_signal = 0;
708 klass->show = gtk_widget_real_show;
709 klass->show_all = gtk_widget_show;
710 klass->hide = gtk_widget_real_hide;
711 klass->hide_all = gtk_widget_hide;
712 klass->map = gtk_widget_real_map;
713 klass->unmap = gtk_widget_real_unmap;
714 klass->realize = gtk_widget_real_realize;
715 klass->unrealize = gtk_widget_real_unrealize;
716 klass->draw = gtk_widget_real_draw;
717 klass->draw_focus = NULL;
718 klass->size_request = gtk_widget_real_size_request;
719 klass->size_allocate = gtk_widget_real_size_allocate;
720 klass->state_changed = NULL;
721 klass->parent_set = NULL;
722 klass->style_set = gtk_widget_style_set;
723 klass->add_accelerator = (void*) gtk_accel_group_handle_add;
724 klass->remove_accelerator = (void*) gtk_accel_group_handle_remove;
726 klass->button_press_event = NULL;
727 klass->button_release_event = NULL;
728 klass->motion_notify_event = NULL;
729 klass->delete_event = NULL;
730 klass->destroy_event = NULL;
731 klass->expose_event = NULL;
732 klass->key_press_event = gtk_widget_real_key_press_event;
733 klass->key_release_event = gtk_widget_real_key_release_event;
734 klass->enter_notify_event = NULL;
735 klass->leave_notify_event = NULL;
736 klass->configure_event = NULL;
737 klass->focus_in_event = NULL;
738 klass->focus_out_event = NULL;
739 klass->map_event = NULL;
740 klass->unmap_event = NULL;
741 klass->property_notify_event = gtk_selection_property_notify;
742 klass->selection_clear_event = gtk_selection_clear;
743 klass->selection_request_event = gtk_selection_request;
744 klass->selection_notify_event = gtk_selection_notify;
745 klass->selection_received = NULL;
746 klass->proximity_in_event = NULL;
747 klass->proximity_out_event = NULL;
748 klass->drag_begin = NULL;
749 klass->drag_end = NULL;
750 klass->drag_data_delete = NULL;
751 klass->drag_leave = NULL;
752 klass->drag_motion = NULL;
753 klass->drag_drop = NULL;
754 klass->drag_data_received = NULL;
756 klass->no_expose_event = NULL;
758 klass->debug_msg = gtk_widget_debug_msg;
762 gtk_widget_set_arg (GtkObject *object,
768 widget = GTK_WIDGET (object);
775 gtk_widget_set_name (widget, GTK_VALUE_STRING (*arg));
778 gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT (*arg)), widget);
781 gtk_widget_set_uposition (widget, GTK_VALUE_INT (*arg), -2);
784 gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT (*arg));
787 gtk_widget_set_usize (widget, GTK_VALUE_INT (*arg), -2);
790 gtk_widget_set_usize (widget, -2, GTK_VALUE_INT (*arg));
793 if (GTK_VALUE_BOOL(*arg))
794 gtk_widget_show (widget);
796 gtk_widget_hide (widget);
799 gtk_widget_set_sensitive (widget, GTK_VALUE_BOOL (*arg));
802 saved_flags = GTK_WIDGET_FLAGS (widget);
803 if (GTK_VALUE_BOOL (*arg))
804 GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
806 GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
807 if (saved_flags != GTK_WIDGET_FLAGS (widget))
808 gtk_widget_queue_resize (widget);
811 if (GTK_VALUE_BOOL (*arg))
812 gtk_widget_grab_focus (widget);
814 case ARG_CAN_DEFAULT:
815 saved_flags = GTK_WIDGET_FLAGS (widget);
816 if (GTK_VALUE_BOOL (*arg))
817 GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
819 GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
820 if (saved_flags != GTK_WIDGET_FLAGS (widget))
821 gtk_widget_queue_resize (widget);
823 case ARG_HAS_DEFAULT:
824 if (GTK_VALUE_BOOL (*arg))
825 gtk_widget_grab_default (widget);
827 case ARG_COMPOSITE_CHILD:
828 if (GTK_VALUE_BOOL(*arg))
829 GTK_WIDGET_SET_FLAGS (widget, GTK_COMPOSITE_CHILD);
831 GTK_WIDGET_UNSET_FLAGS (widget, GTK_COMPOSITE_CHILD);
834 gtk_widget_set_style (widget, (GtkStyle*) GTK_VALUE_BOXED (*arg));
837 if (!GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget))
838 gtk_widget_set_events (widget, GTK_VALUE_FLAGS (*arg));
840 case ARG_EXTENSION_EVENTS:
841 gtk_widget_set_extension_events (widget, GTK_VALUE_FLAGS (*arg));
848 /*****************************************
849 * gtk_widget_get_arg:
854 *****************************************/
857 gtk_widget_get_arg (GtkObject *object,
863 widget = GTK_WIDGET (object);
867 GtkWidgetAuxInfo *aux_info;
869 GdkExtensionMode *modep;
873 GTK_VALUE_STRING (*arg) = g_strdup (widget->name);
875 GTK_VALUE_STRING (*arg) = g_strdup ("");
878 GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
881 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
883 GTK_VALUE_INT (*arg) = -1;
885 GTK_VALUE_INT (*arg) = aux_info->x;
888 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
890 GTK_VALUE_INT (*arg) = -1;
892 GTK_VALUE_INT (*arg) = aux_info->y;
895 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
897 GTK_VALUE_INT (*arg) = -1;
899 GTK_VALUE_INT (*arg) = aux_info->width;
902 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
904 GTK_VALUE_INT (*arg) = -1;
906 GTK_VALUE_INT (*arg) = aux_info->height;
909 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_VISIBLE (widget) != FALSE);
912 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_SENSITIVE (widget) != FALSE);
915 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_FOCUS (widget) != FALSE);
918 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_FOCUS (widget) != FALSE);
920 case ARG_CAN_DEFAULT:
921 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE);
923 case ARG_HAS_DEFAULT:
924 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_HAS_DEFAULT (widget) != FALSE);
926 case ARG_COMPOSITE_CHILD:
927 GTK_VALUE_BOOL (*arg) = (GTK_WIDGET_COMPOSITE_CHILD (widget) != FALSE);
930 GTK_VALUE_BOXED (*arg) = (gpointer) gtk_widget_get_style (widget);
933 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
935 GTK_VALUE_FLAGS (*arg) = 0;
937 GTK_VALUE_FLAGS (*arg) = *eventp;
939 case ARG_EXTENSION_EVENTS:
940 modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
942 GTK_VALUE_FLAGS (*arg) = 0;
944 GTK_VALUE_FLAGS (*arg) = *modep;
947 arg->type = GTK_TYPE_INVALID;
952 /*****************************************
958 *****************************************/
961 gtk_widget_init (GtkWidget *widget)
963 GdkColormap *colormap;
966 GTK_PRIVATE_FLAGS (widget) = 0;
967 widget->state = GTK_STATE_NORMAL;
968 widget->saved_state = GTK_STATE_NORMAL;
970 widget->requisition.width = 0;
971 widget->requisition.height = 0;
972 widget->allocation.x = -1;
973 widget->allocation.y = -1;
974 widget->allocation.width = 1;
975 widget->allocation.height = 1;
976 widget->window = NULL;
977 widget->parent = NULL;
979 GTK_WIDGET_SET_FLAGS (widget,
981 GTK_PARENT_SENSITIVE |
982 (composite_child_stack ? GTK_COMPOSITE_CHILD : 0));
984 widget->style = gtk_widget_peek_style ();
985 gtk_style_ref (widget->style);
987 colormap = gtk_widget_peek_colormap ();
988 visual = gtk_widget_peek_visual ();
990 /* XXX - should we ref the colormap and visual, too? */
992 if (colormap != gtk_widget_get_default_colormap ())
994 /* gdk_colormap_ref (colormap); */
995 gtk_object_set_data (GTK_OBJECT (widget), colormap_key, colormap);
998 if (visual != gtk_widget_get_default_visual ())
1000 /* gdk_visual_ref (visual); */
1001 gtk_object_set_data (GTK_OBJECT (widget), visual_key, visual);
1005 /*****************************************
1011 *****************************************/
1014 gtk_widget_new (GtkType widget_type,
1015 const gchar *first_arg_name,
1020 GSList *arg_list = NULL;
1021 GSList *info_list = NULL;
1024 g_return_val_if_fail (gtk_type_is_a (widget_type, GTK_TYPE_WIDGET), NULL);
1026 object = gtk_type_new (widget_type);
1028 va_start (var_args, first_arg_name);
1029 error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1038 g_warning ("gtk_widget_new(): %s", error);
1046 slist_arg = arg_list;
1047 slist_info = info_list;
1050 gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1051 slist_arg = slist_arg->next;
1052 slist_info = slist_info->next;
1054 gtk_args_collect_cleanup (arg_list, info_list);
1057 return GTK_WIDGET (object);
1060 /*****************************************
1066 *****************************************/
1069 gtk_widget_newv (GtkType type,
1073 g_return_val_if_fail (gtk_type_is_a (type, gtk_widget_get_type ()), NULL);
1075 return GTK_WIDGET (gtk_object_newv (type, nargs, args));
1078 /*****************************************
1084 *****************************************/
1087 gtk_widget_get (GtkWidget *widget,
1090 g_return_if_fail (widget != NULL);
1091 g_return_if_fail (GTK_IS_WIDGET (widget));
1092 g_return_if_fail (arg != NULL);
1094 gtk_object_getv (GTK_OBJECT (widget), 1, arg);
1097 /*****************************************
1103 *****************************************/
1106 gtk_widget_getv (GtkWidget *widget,
1110 g_return_if_fail (widget != NULL);
1111 g_return_if_fail (GTK_IS_WIDGET (widget));
1113 gtk_object_getv (GTK_OBJECT (widget), nargs, args);
1116 /*****************************************
1122 *****************************************/
1125 gtk_widget_set (GtkWidget *widget,
1126 const gchar *first_arg_name,
1131 GSList *arg_list = NULL;
1132 GSList *info_list = NULL;
1135 g_return_if_fail (widget != NULL);
1136 g_return_if_fail (GTK_IS_WIDGET (widget));
1138 object = GTK_OBJECT (widget);
1140 va_start (var_args, first_arg_name);
1141 error = gtk_object_args_collect (GTK_OBJECT_TYPE (object),
1150 g_warning ("gtk_widget_set(): %s", error);
1158 slist_arg = arg_list;
1159 slist_info = info_list;
1162 gtk_object_arg_set (object, slist_arg->data, slist_info->data);
1163 slist_arg = slist_arg->next;
1164 slist_info = slist_info->next;
1166 gtk_args_collect_cleanup (arg_list, info_list);
1170 /*****************************************
1176 *****************************************/
1179 gtk_widget_setv (GtkWidget *widget,
1183 g_return_if_fail (widget != NULL);
1184 g_return_if_fail (GTK_IS_WIDGET (widget));
1186 gtk_object_setv (GTK_OBJECT (widget), nargs, args);
1189 /*****************************************
1190 * gtk_widget_unparent:
1191 * do any cleanup necessary necessary
1192 * for setting parent = NULL.
1197 *****************************************/
1200 gtk_widget_unparent (GtkWidget *widget)
1202 GtkWidget *toplevel;
1203 GtkWidget *old_parent;
1205 g_return_if_fail (widget != NULL);
1206 g_return_if_fail (GTK_IS_WIDGET (widget));
1207 if (widget->parent == NULL)
1210 /* keep this function in sync with gtk_menu_detach()
1213 /* unset focused and default children properly, this code
1214 * should eventually move into some gtk_window_unparent_branch() or
1218 toplevel = gtk_widget_get_toplevel (widget);
1219 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
1221 gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
1223 if (GTK_IS_WINDOW (toplevel))
1227 child = GTK_WINDOW (toplevel)->focus_widget;
1229 while (child && child != widget)
1230 child = child->parent;
1232 if (child == widget)
1233 gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
1236 if (GTK_IS_WINDOW (toplevel))
1240 child = GTK_WINDOW (toplevel)->default_widget;
1242 while (child && child != widget)
1243 child = child->parent;
1245 if (child == widget)
1246 gtk_window_set_default (GTK_WINDOW (toplevel), NULL);
1249 if (GTK_WIDGET_REDRAW_PENDING (widget))
1250 gtk_widget_redraw_queue_remove (widget);
1252 if (GTK_IS_RESIZE_CONTAINER (widget))
1253 gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
1255 /* Remove the widget and all its children from any ->resize_widgets list
1256 * of all the parents in our branch. This code should move into gtkcontainer.c
1257 * somwhen, since we mess around with ->resize_widgets, which is
1258 * actually not of our business.
1260 * Two ways to make this prettier:
1261 * Write a g_slist_conditional_remove (GSList, gboolean (*)(gpointer))
1262 * Change resize_widgets to a GList
1264 toplevel = widget->parent;
1270 if (!GTK_CONTAINER (toplevel)->resize_widgets)
1272 toplevel = toplevel->parent;
1277 slist = GTK_CONTAINER (toplevel)->resize_widgets;
1289 while (parent && (parent != widget))
1290 parent = parent->parent;
1292 if (parent == widget)
1294 GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
1300 /* it is really messy to have this signal disconnection
1301 * in gtkwidget.c, the resize_widgets invariants should
1302 * all be taken care off by gtkcontainer.c exclusively.
1305 gtk_signal_disconnect_by_func (GTK_OBJECT (toplevel),
1306 GTK_SIGNAL_FUNC (gtk_container_clear_resize_widgets),
1308 GTK_CONTAINER (toplevel)->resize_widgets = slist;
1311 g_slist_free_1 (last);
1317 toplevel = toplevel->parent;
1319 if (widget->window &&
1320 GTK_WIDGET_NO_WINDOW (widget) &&
1321 GTK_WIDGET_DRAWABLE (widget))
1322 gtk_widget_queue_clear (widget);
1324 /* Reset the width and height here, to force reallocation if we
1325 * get added back to a new parent. This won't work if our new
1326 * allocation is smaller than 1x1 and we actually want a size of 1x1...
1327 * (would 0x0 be OK here?)
1329 widget->allocation.width = 1;
1330 widget->allocation.height = 1;
1332 if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_IN_REPARENT (widget))
1333 gtk_widget_unrealize (widget);
1335 old_parent = widget->parent;
1336 widget->parent = NULL;
1337 gtk_widget_set_parent_window (widget, NULL);
1338 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], old_parent);
1340 gtk_widget_unref (widget);
1343 /*****************************************
1344 * gtk_widget_destroy:
1349 *****************************************/
1352 gtk_widget_destroy (GtkWidget *widget)
1354 g_return_if_fail (widget != NULL);
1355 g_return_if_fail (GTK_IS_WIDGET (widget));
1357 gtk_object_destroy ((GtkObject*) widget);
1360 /*****************************************
1361 * gtk_widget_destroyed:
1362 * Utility function: sets widget_pointer
1363 * to NULL when widget is destroyed.
1368 *****************************************/
1371 gtk_widget_destroyed (GtkWidget *widget,
1372 GtkWidget **widget_pointer)
1374 /* Don't make any assumptions about the
1376 * Even check widget_pointer.
1379 *widget_pointer = NULL;
1382 /*****************************************
1388 *****************************************/
1391 gtk_widget_show (GtkWidget *widget)
1393 g_return_if_fail (widget != NULL);
1394 g_return_if_fail (GTK_IS_WIDGET (widget));
1396 if (!GTK_WIDGET_VISIBLE (widget))
1397 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SHOW]);
1401 /*************************************************************
1402 * gtk_widget_show_now:
1403 * Show a widget, and if it is an unmapped toplevel widget
1404 * wait for the map_event before returning
1406 * Warning: This routine will call the main loop recursively.
1411 *************************************************************/
1414 gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
1417 gtk_signal_disconnect_by_data (GTK_OBJECT (widget), flag);
1421 gtk_widget_show_now (GtkWidget *widget)
1425 g_return_if_fail (widget != NULL);
1426 g_return_if_fail (GTK_IS_WIDGET (widget));
1428 /* make sure we will get event */
1429 if (!GTK_WIDGET_MAPPED (widget) &&
1430 GTK_WIDGET_TOPLEVEL (widget))
1432 gtk_widget_show (widget);
1434 gtk_signal_connect (GTK_OBJECT (widget), "map_event",
1435 GTK_SIGNAL_FUNC (gtk_widget_show_map_callback),
1439 gtk_main_iteration();
1442 gtk_widget_show (widget);
1445 /*****************************************
1451 *****************************************/
1454 gtk_widget_hide (GtkWidget *widget)
1456 g_return_if_fail (widget != NULL);
1457 g_return_if_fail (GTK_IS_WIDGET (widget));
1459 if (GTK_WIDGET_VISIBLE (widget))
1460 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[HIDE]);
1464 gtk_widget_hide_on_delete (GtkWidget *widget)
1466 g_return_val_if_fail (widget != NULL, FALSE);
1467 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1469 gtk_widget_hide (widget);
1475 gtk_widget_show_all (GtkWidget *widget)
1477 GtkWidgetClass *class;
1479 g_return_if_fail (widget != NULL);
1480 g_return_if_fail (GTK_IS_WIDGET (widget));
1482 class = GTK_WIDGET_CLASS (GTK_OBJECT (widget)->klass);
1484 if (class->show_all)
1485 class->show_all (widget);
1489 gtk_widget_hide_all (GtkWidget *widget)
1491 GtkWidgetClass *class;
1493 g_return_if_fail (widget != NULL);
1494 g_return_if_fail (GTK_IS_WIDGET (widget));
1496 class = GTK_WIDGET_CLASS (GTK_OBJECT (widget)->klass);
1498 if (class->hide_all)
1499 class->hide_all (widget);
1502 /*****************************************
1508 *****************************************/
1511 gtk_widget_map (GtkWidget *widget)
1513 g_return_if_fail (widget != NULL);
1514 g_return_if_fail (GTK_IS_WIDGET (widget));
1516 if (!GTK_WIDGET_MAPPED (widget))
1518 if (!GTK_WIDGET_REALIZED (widget))
1519 gtk_widget_realize (widget);
1521 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
1525 /*****************************************
1531 *****************************************/
1534 gtk_widget_unmap (GtkWidget *widget)
1536 g_return_if_fail (widget != NULL);
1537 g_return_if_fail (GTK_IS_WIDGET (widget));
1539 if (GTK_WIDGET_MAPPED (widget))
1540 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
1543 /*****************************************
1544 * gtk_widget_realize:
1549 *****************************************/
1552 gtk_widget_realize (GtkWidget *widget)
1555 GdkExtensionMode mode;
1556 GtkWidgetShapeInfo *shape_info;
1558 g_return_if_fail (widget != NULL);
1559 g_return_if_fail (GTK_IS_WIDGET (widget));
1561 if (!GTK_WIDGET_REALIZED (widget))
1564 if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
1565 g_message ("gtk_widget_realize(%s)", gtk_type_name (GTK_WIDGET_TYPE (widget)));
1568 if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
1569 gtk_widget_realize (widget->parent);
1571 gtk_widget_ensure_style (widget);
1573 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);
1575 if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1577 shape_info = gtk_object_get_data (GTK_OBJECT (widget),
1579 gdk_window_shape_combine_mask (widget->window,
1580 shape_info->shape_mask,
1581 shape_info->offset_x,
1582 shape_info->offset_y);
1585 if (!GTK_WIDGET_NO_WINDOW (widget))
1587 mode = gtk_widget_get_extension_events (widget);
1588 if (mode != GDK_EXTENSION_EVENTS_NONE)
1590 events = gtk_widget_get_events (widget);
1591 gdk_input_set_extension_events (widget->window, events, mode);
1598 /*****************************************
1599 * gtk_widget_unrealize:
1604 *****************************************/
1607 gtk_widget_unrealize (GtkWidget *widget)
1609 g_return_if_fail (widget != NULL);
1610 g_return_if_fail (GTK_IS_WIDGET (widget));
1612 if (GTK_WIDGET_REDRAW_PENDING (widget))
1613 gtk_widget_redraw_queue_remove (widget);
1615 if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
1616 gtk_widget_shape_combine_mask (widget, NULL, -1, -1);
1618 if (GTK_WIDGET_REALIZED (widget))
1620 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);
1621 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
1625 /*****************************************
1626 * gtk_widget_queue_draw:
1631 *****************************************/
1633 typedef struct _GtkDrawData GtkDrawData;
1634 struct _GtkDrawData {
1639 static GMemChunk *draw_data_mem_chunk = NULL;
1640 static GSList *draw_data_free_list = NULL;
1641 static const gchar *draw_data_key = "gtk-draw-data";
1642 static guint draw_data_key_id = 0;
1644 static gint gtk_widget_idle_draw (gpointer data);
1647 gtk_widget_queue_draw_data (GtkWidget *widget,
1657 g_return_if_fail (widget != NULL);
1659 if ((width != 0) && (height != 0) && GTK_WIDGET_DRAWABLE (widget))
1661 if (!draw_data_key_id)
1662 draw_data_key_id = g_quark_from_static_string (draw_data_key);
1664 if (draw_data_free_list)
1666 node = draw_data_free_list;
1668 draw_data_free_list = draw_data_free_list->next;
1672 if (!draw_data_mem_chunk)
1673 draw_data_mem_chunk = g_mem_chunk_create (GtkDrawData, 64,
1675 data = g_chunk_new (GtkDrawData, draw_data_mem_chunk);
1676 node = g_slist_alloc();
1683 if ((width < 0) || (height < 0))
1685 data->rect.width = 0;
1686 data->rect.height = 0;
1690 data->rect.width = width;
1691 data->rect.height = height;
1693 data->window = window;
1695 if ((width < 0) || (height < 0))
1697 GSList *draw_data_list =
1698 gtk_object_get_data_by_id (GTK_OBJECT (widget),
1701 draw_data_free_list = g_slist_concat (draw_data_list,
1702 draw_data_free_list);
1706 node->next = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1709 if (!GTK_WIDGET_REDRAW_PENDING (widget))
1711 GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_PENDING);
1712 if (gtk_widget_redraw_queue == NULL)
1713 gtk_idle_add_priority (GTK_PRIORITY_INTERNAL,
1714 gtk_widget_idle_draw,
1716 gtk_widget_redraw_queue = g_slist_prepend (gtk_widget_redraw_queue, widget);
1719 gtk_object_set_data_by_id (GTK_OBJECT (widget), draw_data_key_id, node);
1724 gtk_widget_queue_draw_area (GtkWidget *widget,
1730 g_return_if_fail (widget != NULL);
1731 g_return_if_fail (GTK_IS_WIDGET (widget));
1733 gtk_widget_queue_draw_data (widget, x, y, width, height, NULL);
1737 gtk_widget_queue_draw (GtkWidget *widget)
1739 g_return_if_fail (widget != NULL);
1740 g_return_if_fail (GTK_IS_WIDGET (widget));
1742 gtk_widget_queue_draw_data (widget, 0, 0, -1, -1, NULL);
1746 gtk_widget_queue_clear_area (GtkWidget *widget,
1754 g_return_if_fail (widget != NULL);
1755 g_return_if_fail (GTK_IS_WIDGET (widget));
1757 /* Find the correct widget */
1759 if (GTK_WIDGET_NO_WINDOW (widget))
1762 while (parent && GTK_WIDGET_NO_WINDOW (parent))
1763 parent = parent->parent;
1766 gtk_widget_queue_draw_data (parent, x, y, width, height, widget->window);
1770 gint wx, wy, wwidth, wheight;
1771 /* Translate widget relative to window-relative */
1773 gdk_window_get_position (widget->window, &wx, &wy);
1774 x -= wx - widget->allocation.x;
1775 y -= wy - widget->allocation.y;
1777 gdk_window_get_size (widget->window, &wwidth, &wheight);
1787 if (x + width > wwidth)
1789 if (y + height > wheight)
1790 height = wheight - y;
1792 gtk_widget_queue_draw_data (widget, x, y, width, height, NULL);
1797 gtk_widget_redraw_queue_remove (GtkWidget *widget)
1799 GSList *draw_data_list;
1802 g_return_if_fail (GTK_WIDGET_REDRAW_PENDING (widget));
1804 gtk_widget_redraw_queue = g_slist_remove (gtk_widget_redraw_queue, widget);
1806 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1808 tmp_list = g_slist_last (draw_data_list);
1811 tmp_list->next = draw_data_free_list;
1812 draw_data_free_list = draw_data_list;
1815 gtk_object_set_data_by_id (GTK_OBJECT (widget),
1819 GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
1823 gtk_widget_queue_clear (GtkWidget *widget)
1825 g_return_if_fail (widget != NULL);
1826 g_return_if_fail (GTK_IS_WIDGET (widget));
1828 if (GTK_WIDGET_NO_WINDOW (widget))
1829 gtk_widget_queue_clear_area (widget, widget->allocation.x,
1830 widget->allocation.y,
1831 widget->allocation.width,
1832 widget->allocation.height);
1834 gtk_widget_queue_clear_area (widget, 0, 0,
1835 widget->allocation.width,
1836 widget->allocation.height);
1840 gtk_widget_draw_data_combine (GtkDrawData *parent, GtkDrawData *child)
1842 gint parent_x2, parent_y2;
1843 gint child_x2, child_y2;
1845 /* Check for intersection */
1847 parent_x2 = parent->rect.x + parent->rect.width;
1848 child_x2 = child->rect.x + child->rect.width;
1849 parent_y2 = parent->rect.y + parent->rect.height;
1850 child_y2 = child->rect.y + child->rect.height;
1852 if ((child->rect.x > parent_x2) || (parent->rect.x > child_x2) ||
1853 (child->rect.y > parent_y2) || (parent->rect.y > child_y2))
1857 parent->rect.x = MIN (parent->rect.x, child->rect.x);
1858 parent->rect.y = MIN (parent->rect.y, child->rect.y);
1859 parent->rect.width = MAX (parent_x2, child_x2) - parent->rect.x;
1860 parent->rect.height = MAX (parent_y2, child_y2) - parent->rect.y;
1866 /* Take a rectangle with respect to window, and translate it
1867 * to coordinates relative to widget's allocation, clipping through
1868 * intermediate windows. Returns whether translation failed. If the
1869 * translation failed, we have something like a handlebox, where
1870 * the child widget's GdkWindow is not a child of the parents GdkWindow.
1873 gtk_widget_clip_rect (GtkWidget *widget,
1879 gint x,y, width, height;
1881 while (window && (window != widget->window))
1883 gdk_window_get_position (window, &x, &y);
1891 window = gdk_window_get_parent (window);
1895 gdk_window_get_size (window, &width, &height);
1899 rect->width += rect->x;
1904 rect->height += rect->y;
1907 if (rect->x + rect->width > width)
1908 rect->width = width - rect->x;
1909 if (rect->y + rect->height > height)
1910 rect->height = height - rect->y;
1916 if (!GTK_WIDGET_NO_WINDOW (widget))
1918 if (gdk_window_get_toplevel (window) != window)
1920 gdk_window_get_position (window, &x, &y);
1921 rect->x += x - widget->allocation.x;
1923 *x_offset += x - widget->allocation.x;
1924 rect->y += y - widget->allocation.y;
1926 *y_offset += y - widget->allocation.y;
1934 gtk_widget_idle_draw (gpointer data)
1936 GSList *widget_list;
1937 GSList *draw_data_list;
1940 /* Translate all draw requests to be allocation-relative */
1941 widget_list = gtk_widget_redraw_queue;
1944 widget = widget_list->data;
1945 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1948 while (draw_data_list)
1950 gboolean full_allocation = FALSE;
1951 GtkDrawData *data = draw_data_list->data;
1955 /* If the translation fails, we have a handlebox,
1956 * so redraw the whole widget. Could be done better?
1958 full_allocation = !gtk_widget_clip_rect (widget,
1962 data->window = NULL;
1966 if ((data->rect.width == 0) && (data->rect.height == 0))
1968 if (GTK_WIDGET_NO_WINDOW (widget))
1970 data->rect.x = widget->allocation.x;
1971 data->rect.y = widget->allocation.y;
1978 data->rect.width = widget->allocation.width;
1979 data->rect.height = widget->allocation.height;
1983 draw_data_list = draw_data_list->next;
1986 widget_list = widget_list->next;
1991 widget_list = gtk_widget_redraw_queue;
1994 GSList *prev_node = NULL;
1995 widget = widget_list->data;
1996 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
1999 while (draw_data_list)
2001 gint x_offset, y_offset;
2002 GtkDrawData *data = draw_data_list->data;
2003 GSList *parent_list = draw_data_list->next;
2015 if (gtk_widget_draw_data_combine (parent_list->data, data))
2019 prev_node->next = draw_data_list->next;
2021 gtk_object_set_data_by_id (GTK_OBJECT (widget),
2023 draw_data_list->next);
2025 tmp = draw_data_list->next;
2026 draw_data_list->next = draw_data_free_list;
2027 draw_data_free_list = draw_data_list;
2028 draw_data_list = tmp;
2033 parent_list = parent_list->next;
2036 window = parent->window;
2038 if (parent->parent && parent->parent->window != window)
2040 if (!GTK_WIDGET_NO_WINDOW (parent))
2043 gdk_window_get_position (window, &x, &y);
2044 data->rect.x -= x - parent->allocation.x;
2045 x_offset -= x - parent->allocation.x;
2046 data->rect.y -= y - parent->allocation.y;
2047 y_offset -= y - parent->allocation.y;
2049 /* If we can't translate the rectangle, stop trying to
2050 * merge. (This occurs for a handlebox)
2052 if (!gtk_widget_clip_rect (parent->parent, window, &data->rect,
2053 &x_offset, &y_offset))
2058 parent = parent->parent;
2060 if (parent && GTK_WIDGET_REDRAW_PENDING (parent))
2061 parent_list = gtk_object_get_data_by_id (GTK_OBJECT (parent),
2067 /* OK, this rectangle stays around. But take advantage
2068 * of the work we've done to clip it to the visible area -
2069 * rect.width/height have already been appropriately
2072 data->rect.x -= x_offset;
2073 data->rect.y -= y_offset;
2076 prev_node = draw_data_list;
2078 draw_data_list = draw_data_list->next;
2082 widget_list = widget_list->next;
2085 /* Process the draws */
2087 widget_list = gtk_widget_redraw_queue;
2091 widget = widget_list->data;
2092 draw_data_list = gtk_object_get_data_by_id (GTK_OBJECT (widget),
2094 gtk_object_set_data_by_id (GTK_OBJECT (widget),
2098 GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_PENDING);
2100 while (draw_data_list)
2102 GtkDrawData *data = draw_data_list->data;
2103 gtk_widget_draw (widget, &data->rect);
2105 if (draw_data_list->next)
2106 draw_data_list = draw_data_list->next;
2109 draw_data_list->next = draw_data_free_list;
2110 draw_data_free_list = draw_data_list;
2115 widget_list = widget_list->next;
2118 g_slist_free (gtk_widget_redraw_queue);
2119 gtk_widget_redraw_queue = NULL;
2125 gtk_widget_queue_resize (GtkWidget *widget)
2127 g_return_if_fail (widget != NULL);
2128 g_return_if_fail (GTK_IS_WIDGET (widget));
2130 if (GTK_IS_RESIZE_CONTAINER (widget))
2131 gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
2134 gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
2135 else if (GTK_WIDGET_TOPLEVEL (widget))
2136 gtk_container_queue_resize (GTK_CONTAINER (widget));
2139 /*****************************************
2145 *****************************************/
2148 gtk_widget_draw (GtkWidget *widget,
2151 GdkRectangle temp_area;
2153 g_return_if_fail (widget != NULL);
2154 g_return_if_fail (GTK_IS_WIDGET (widget));
2156 if (GTK_WIDGET_DRAWABLE (widget))
2160 if (GTK_WIDGET_NO_WINDOW (widget))
2162 temp_area.x = widget->allocation.x;
2163 temp_area.y = widget->allocation.y;
2171 temp_area.width = widget->allocation.width;
2172 temp_area.height = widget->allocation.height;
2176 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area);
2180 /*****************************************
2181 * gtk_widget_draw_focus:
2186 *****************************************/
2189 gtk_widget_draw_focus (GtkWidget *widget)
2191 g_return_if_fail (widget != NULL);
2192 g_return_if_fail (GTK_IS_WIDGET (widget));
2194 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_FOCUS]);
2197 /*****************************************
2198 * gtk_widget_draw_default:
2203 *****************************************/
2206 gtk_widget_draw_default (GtkWidget *widget)
2208 g_return_if_fail (widget != NULL);
2209 g_return_if_fail (GTK_IS_WIDGET (widget));
2211 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_DEFAULT]);
2214 /*****************************************
2215 * gtk_widget_draw_children:
2220 *****************************************/
2223 gtk_widget_draw_children (GtkWidget *widget)
2225 g_return_if_fail (widget != NULL);
2226 g_return_if_fail (GTK_IS_WIDGET (widget));
2228 if (GTK_IS_CONTAINER (widget))
2229 gtk_container_forall (GTK_CONTAINER (widget),
2230 gtk_widget_draw_children_recurse,
2234 /*****************************************
2235 * gtk_widget_size_request:
2240 *****************************************/
2243 gtk_widget_size_request (GtkWidget *widget,
2244 GtkRequisition *requisition)
2246 GtkWidgetAuxInfo *aux_info;
2248 g_return_if_fail (widget != NULL);
2249 g_return_if_fail (GTK_IS_WIDGET (widget));
2251 gtk_widget_ref (widget);
2252 gtk_widget_ensure_style (widget);
2253 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST],
2255 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
2258 if (aux_info->width > 0)
2259 requisition->width = aux_info->width;
2260 if (aux_info->height > 0)
2261 requisition->height = aux_info->height;
2263 gtk_widget_unref (widget);
2266 /*****************************************
2267 * gtk_widget_size_allocate:
2272 *****************************************/
2275 gtk_widget_size_allocate (GtkWidget *widget,
2276 GtkAllocation *allocation)
2278 GtkWidgetAuxInfo *aux_info;
2279 GtkAllocation real_allocation;
2281 g_return_if_fail (widget != NULL);
2282 g_return_if_fail (GTK_IS_WIDGET (widget));
2284 real_allocation = *allocation;
2285 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
2289 if (aux_info->x != -1)
2290 real_allocation.x = aux_info->x;
2291 if (aux_info->y != -1)
2292 real_allocation.y = aux_info->y;
2295 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
2299 gtk_widget_stop_add_accelerator (GtkWidget *widget)
2301 g_return_if_fail (widget != NULL);
2302 g_return_if_fail (GTK_IS_WIDGET (widget));
2304 gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[ADD_ACCELERATOR]);
2308 gtk_widget_stop_remove_accelerator (GtkWidget *widget)
2310 g_return_if_fail (widget != NULL);
2311 g_return_if_fail (GTK_IS_WIDGET (widget));
2313 gtk_signal_emit_stop (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR]);
2317 gtk_widget_freeze_accelerators (GtkWidget *widget)
2319 g_return_if_fail (widget != NULL);
2320 g_return_if_fail (GTK_IS_WIDGET (widget));
2322 if (gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
2323 widget_signals[ADD_ACCELERATOR],
2325 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2328 gtk_signal_connect (GTK_OBJECT (widget),
2330 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2332 gtk_signal_connect (GTK_OBJECT (widget),
2333 "remove_accelerator",
2334 GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2340 gtk_widget_thaw_accelerators (GtkWidget *widget)
2342 g_return_if_fail (widget != NULL);
2343 g_return_if_fail (GTK_IS_WIDGET (widget));
2345 if (gtk_signal_handler_pending_by_func (GTK_OBJECT (widget),
2346 widget_signals[ADD_ACCELERATOR],
2348 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2351 gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2352 GTK_SIGNAL_FUNC (gtk_widget_stop_add_accelerator),
2354 gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
2355 GTK_SIGNAL_FUNC (gtk_widget_stop_remove_accelerator),
2361 gtk_widget_add_accelerator (GtkWidget *widget,
2362 const gchar *accel_signal,
2363 GtkAccelGroup *accel_group,
2366 GtkAccelFlags accel_flags)
2368 g_return_if_fail (widget != NULL);
2369 g_return_if_fail (GTK_IS_WIDGET (widget));
2370 g_return_if_fail (accel_group != NULL);
2372 gtk_accel_group_add (accel_group,
2376 (GtkObject*) widget,
2381 gtk_widget_remove_accelerator (GtkWidget *widget,
2382 GtkAccelGroup *accel_group,
2386 g_return_if_fail (widget != NULL);
2387 g_return_if_fail (GTK_IS_WIDGET (widget));
2388 g_return_if_fail (accel_group != NULL);
2390 gtk_accel_group_remove (accel_group,
2393 (GtkObject*) widget);
2397 gtk_widget_remove_accelerators (GtkWidget *widget,
2398 const gchar *accel_signal,
2399 gboolean visible_only)
2404 g_return_if_fail (widget != NULL);
2405 g_return_if_fail (GTK_IS_WIDGET (widget));
2406 g_return_if_fail (accel_signal != NULL);
2408 signal_id = gtk_signal_lookup (accel_signal, GTK_OBJECT_TYPE (widget));
2409 g_return_if_fail (signal_id != 0);
2411 slist = gtk_accel_group_entries_from_object (GTK_OBJECT (widget));
2414 GtkAccelEntry *ac_entry;
2416 ac_entry = slist->data;
2417 slist = slist->next;
2418 if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE &&
2419 ac_entry->signal_id == signal_id)
2420 gtk_widget_remove_accelerator (GTK_WIDGET (widget),
2421 ac_entry->accel_group,
2422 ac_entry->accelerator_key,
2423 ac_entry->accelerator_mods);
2428 gtk_widget_accelerator_signal (GtkWidget *widget,
2429 GtkAccelGroup *accel_group,
2433 GtkAccelEntry *ac_entry;
2435 g_return_val_if_fail (widget != NULL, 0);
2436 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
2437 g_return_val_if_fail (accel_group != NULL, 0);
2439 ac_entry = gtk_accel_group_get_entry (accel_group, accel_key, accel_mods);
2441 if (ac_entry && ac_entry->object == (GtkObject*) widget)
2442 return ac_entry->signal_id;
2447 gtk_widget_real_key_press_event (GtkWidget *widget,
2450 gboolean handled = FALSE;
2452 g_return_val_if_fail (widget != NULL, handled);
2453 g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2454 g_return_val_if_fail (event != NULL, handled);
2457 handled = gtk_bindings_activate (GTK_OBJECT (widget),
2465 gtk_widget_real_key_release_event (GtkWidget *widget,
2468 gboolean handled = FALSE;
2470 g_return_val_if_fail (widget != NULL, handled);
2471 g_return_val_if_fail (GTK_IS_WIDGET (widget), handled);
2472 g_return_val_if_fail (event != NULL, handled);
2475 handled = gtk_bindings_activate (GTK_OBJECT (widget),
2477 event->state | GDK_RELEASE_MASK);
2482 /*****************************************
2488 *****************************************/
2491 gtk_widget_event (GtkWidget *widget,
2497 g_return_val_if_fail (widget != NULL, TRUE);
2498 g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
2500 gtk_widget_ref (widget);
2502 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event,
2504 if (return_val || GTK_OBJECT_DESTROYED (widget))
2506 gtk_widget_unref (widget);
2510 switch (event->type)
2515 case GDK_BUTTON_PRESS:
2516 case GDK_2BUTTON_PRESS:
2517 case GDK_3BUTTON_PRESS:
2518 signal_num = BUTTON_PRESS_EVENT;
2520 case GDK_BUTTON_RELEASE:
2521 signal_num = BUTTON_RELEASE_EVENT;
2523 case GDK_MOTION_NOTIFY:
2524 signal_num = MOTION_NOTIFY_EVENT;
2527 signal_num = DELETE_EVENT;
2530 signal_num = DESTROY_EVENT;
2533 signal_num = KEY_PRESS_EVENT;
2535 case GDK_KEY_RELEASE:
2536 signal_num = KEY_RELEASE_EVENT;
2538 case GDK_ENTER_NOTIFY:
2539 signal_num = ENTER_NOTIFY_EVENT;
2541 case GDK_LEAVE_NOTIFY:
2542 signal_num = LEAVE_NOTIFY_EVENT;
2544 case GDK_FOCUS_CHANGE:
2545 if (event->focus_change.in)
2546 signal_num = FOCUS_IN_EVENT;
2548 signal_num = FOCUS_OUT_EVENT;
2551 signal_num = CONFIGURE_EVENT;
2554 signal_num = MAP_EVENT;
2557 signal_num = UNMAP_EVENT;
2559 case GDK_PROPERTY_NOTIFY:
2560 signal_num = PROPERTY_NOTIFY_EVENT;
2562 case GDK_SELECTION_CLEAR:
2563 signal_num = SELECTION_CLEAR_EVENT;
2565 case GDK_SELECTION_REQUEST:
2566 signal_num = SELECTION_REQUEST_EVENT;
2568 case GDK_SELECTION_NOTIFY:
2569 signal_num = SELECTION_NOTIFY_EVENT;
2571 case GDK_PROXIMITY_IN:
2572 signal_num = PROXIMITY_IN_EVENT;
2574 case GDK_PROXIMITY_OUT:
2575 signal_num = PROXIMITY_OUT_EVENT;
2578 signal_num = NO_EXPOSE_EVENT;
2580 case GDK_CLIENT_EVENT:
2581 signal_num = CLIENT_EVENT;
2584 /* there is no sense in providing a widget with bogus expose events.
2585 * Widgets that are going to be resized don't need to be
2586 * exposed, since they will be redrawn anyways.
2588 if (!event->any.window ||
2589 GTK_WIDGET_RESIZE_NEEDED (widget) ||
2590 (widget->parent && GTK_WIDGET_RESIZE_NEEDED (widget->parent)))
2592 gtk_widget_unref (widget);
2595 signal_num = EXPOSE_EVENT;
2597 case GDK_VISIBILITY_NOTIFY:
2598 signal_num = VISIBILITY_NOTIFY_EVENT;
2601 g_warning ("could not determine signal number for event: %d", event->type);
2602 gtk_widget_unref (widget);
2606 if (signal_num != -1)
2607 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val);
2609 return_val |= GTK_OBJECT_DESTROYED (widget);
2611 gtk_widget_unref (widget);
2616 /*****************************************
2617 * gtk_widget_activate:
2622 *****************************************/
2625 gtk_widget_activate (GtkWidget *widget)
2627 g_return_if_fail (widget != NULL);
2628 g_return_if_fail (GTK_IS_WIDGET (widget));
2630 if (WIDGET_CLASS (widget)->activate_signal)
2631 gtk_signal_emit (GTK_OBJECT (widget), WIDGET_CLASS (widget)->activate_signal);
2634 /*****************************************
2635 * gtk_widget_reparent_container_child:
2636 * assistent function to gtk_widget_reparent
2641 *****************************************/
2644 gtk_widget_reparent_container_child (GtkWidget *widget,
2645 gpointer client_data)
2647 g_return_if_fail (widget != NULL);
2648 g_return_if_fail (GTK_IS_WIDGET (widget));
2649 g_return_if_fail (client_data != NULL);
2651 if (GTK_WIDGET_NO_WINDOW (widget))
2654 gdk_window_unref (widget->window);
2655 widget->window = (GdkWindow*) client_data;
2657 gdk_window_ref (widget->window);
2659 if (GTK_IS_CONTAINER (widget))
2660 gtk_container_forall (GTK_CONTAINER (widget),
2661 gtk_widget_reparent_container_child,
2665 gdk_window_reparent (widget->window,
2666 (GdkWindow*) client_data, 0, 0);
2669 /*****************************************
2670 * gtk_widget_reparent:
2675 *****************************************/
2678 gtk_widget_reparent (GtkWidget *widget,
2679 GtkWidget *new_parent)
2681 g_return_if_fail (widget != NULL);
2682 g_return_if_fail (GTK_IS_WIDGET (widget));
2683 g_return_if_fail (new_parent != NULL);
2684 g_return_if_fail (GTK_IS_CONTAINER (new_parent));
2685 g_return_if_fail (widget->parent != NULL);
2687 if (widget->parent != new_parent)
2689 /* First try to see if we can get away without unrealizing
2690 * the widget as we reparent it. if so we set a flag so
2691 * that gtk_widget_unparent doesn't unrealize widget
2693 if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
2694 GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
2696 gtk_widget_ref (widget);
2697 gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
2698 gtk_container_add (GTK_CONTAINER (new_parent), widget);
2699 gtk_widget_unref (widget);
2701 if (GTK_WIDGET_IN_REPARENT (widget))
2703 GTK_PRIVATE_UNSET_FLAG (widget, GTK_IN_REPARENT);
2705 /* OK, now fix up the widget's window. (And that for any
2706 * children, if the widget is NO_WINDOW and a container)
2708 if (GTK_WIDGET_NO_WINDOW (widget))
2710 if (GTK_IS_CONTAINER (widget))
2711 gtk_container_forall (GTK_CONTAINER (widget),
2712 gtk_widget_reparent_container_child,
2713 gtk_widget_get_parent_window (widget));
2716 GdkWindow *parent_window;
2718 parent_window = gtk_widget_get_parent_window (widget);
2719 if (parent_window != widget->window)
2722 gdk_window_unref (widget->window);
2723 widget->window = parent_window;
2725 gdk_window_ref (widget->window);
2730 gdk_window_reparent (widget->window, gtk_widget_get_parent_window (widget), 0, 0);
2735 /*****************************************
2741 *****************************************/
2744 gtk_widget_popup (GtkWidget *widget,
2748 g_return_if_fail (widget != NULL);
2749 g_return_if_fail (GTK_IS_WIDGET (widget));
2751 if (!GTK_WIDGET_VISIBLE (widget))
2753 if (!GTK_WIDGET_REALIZED (widget))
2754 gtk_widget_realize (widget);
2755 if (!GTK_WIDGET_NO_WINDOW (widget))
2756 gdk_window_move (widget->window, x, y);
2757 gtk_widget_show (widget);
2761 /*****************************************
2762 * gtk_widget_intersect:
2767 *****************************************/
2770 gtk_widget_intersect (GtkWidget *widget,
2772 GdkRectangle *intersection)
2778 g_return_val_if_fail (widget != NULL, FALSE);
2779 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2780 g_return_val_if_fail (area != NULL, FALSE);
2783 dest = intersection;
2787 return_val = gdk_rectangle_intersect ((GdkRectangle*) &widget->allocation, area, dest);
2789 if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
2791 intersection->x -= widget->allocation.x;
2792 intersection->y -= widget->allocation.y;
2800 gtk_widget_basic (GtkWidget *widget)
2806 g_return_val_if_fail (widget != NULL, FALSE);
2807 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
2809 if (!GTK_WIDGET_BASIC (widget))
2811 else if (GTK_IS_CONTAINER (widget))
2813 children = gtk_container_children (GTK_CONTAINER (widget));
2817 tmp_list = children;
2821 if (!gtk_widget_basic (GTK_WIDGET (tmp_list->data)))
2827 tmp_list = tmp_list->next;
2830 g_list_free (children);
2839 /*****************************************
2840 * gtk_widget_grab_focus:
2845 *****************************************/
2848 gtk_widget_grab_focus (GtkWidget *widget)
2850 g_return_if_fail (widget != NULL);
2851 g_return_if_fail (GTK_IS_WIDGET (widget));
2853 if (GTK_WIDGET_CAN_FOCUS (widget))
2857 GtkType window_type;
2859 window_type = gtk_window_get_type ();
2860 parent = widget->parent;
2863 while (parent && !gtk_type_is_a (GTK_WIDGET_TYPE (parent), window_type))
2865 gtk_container_set_focus_child (GTK_CONTAINER (parent), child);
2867 parent = parent->parent;
2870 if (parent && gtk_type_is_a (GTK_WIDGET_TYPE (parent), window_type))
2872 gtk_container_set_focus_child (GTK_CONTAINER (parent), child);
2873 gtk_window_set_focus (GTK_WINDOW (parent), widget);
2878 /*****************************************
2879 * gtk_widget_grab_default:
2884 *****************************************/
2887 gtk_widget_grab_default (GtkWidget *widget)
2890 GtkType window_type;
2892 g_return_if_fail (widget != NULL);
2893 g_return_if_fail (GTK_IS_WIDGET (widget));
2894 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
2896 window_type = gtk_window_get_type ();
2897 window = widget->parent;
2899 while (window && !gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2900 window = window->parent;
2902 if (window && gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
2903 gtk_window_set_default (GTK_WINDOW (window), widget);
2906 /*****************************************
2907 * gtk_widget_set_name:
2912 *****************************************/
2915 gtk_widget_set_name (GtkWidget *widget,
2918 g_return_if_fail (widget != NULL);
2919 g_return_if_fail (GTK_IS_WIDGET (widget));
2922 g_free (widget->name);
2923 widget->name = g_strdup (name);
2925 if (!GTK_WIDGET_USER_STYLE (widget))
2926 gtk_widget_set_rc_style (widget);
2929 /*****************************************
2930 * gtk_widget_get_name:
2935 *****************************************/
2938 gtk_widget_get_name (GtkWidget *widget)
2940 g_return_val_if_fail (widget != NULL, NULL);
2941 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
2944 return widget->name;
2945 return gtk_type_name (GTK_WIDGET_TYPE (widget));
2948 /*****************************************
2949 * gtk_widget_set_state:
2956 *****************************************/
2959 gtk_widget_set_state (GtkWidget *widget,
2962 g_return_if_fail (widget != NULL);
2963 g_return_if_fail (GTK_IS_WIDGET (widget));
2965 if (state == GTK_WIDGET_STATE (widget))
2968 if (state == GTK_STATE_INSENSITIVE)
2969 gtk_widget_set_sensitive (widget, FALSE);
2975 data.state_restoration = FALSE;
2976 data.use_forall = FALSE;
2978 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
2980 data.parent_sensitive = TRUE;
2982 gtk_widget_propagate_state (widget, &data);
2984 if (GTK_WIDGET_DRAWABLE (widget))
2985 gtk_widget_queue_clear (widget);
2989 /*****************************************
2990 * gtk_widget_set_sensitive:
2994 * boolean value for sensitivity
2997 *****************************************/
3000 gtk_widget_set_sensitive (GtkWidget *widget,
3005 g_return_if_fail (widget != NULL);
3006 g_return_if_fail (GTK_IS_WIDGET (widget));
3008 sensitive = (sensitive != FALSE);
3010 if (sensitive == (GTK_WIDGET_SENSITIVE (widget) != FALSE))
3015 GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
3016 data.state = GTK_WIDGET_SAVED_STATE (widget);
3020 GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
3021 data.state = GTK_WIDGET_STATE (widget);
3023 data.state_restoration = TRUE;
3024 data.use_forall = TRUE;
3027 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
3029 data.parent_sensitive = TRUE;
3031 gtk_widget_propagate_state (widget, &data);
3032 if (GTK_WIDGET_DRAWABLE (widget))
3033 gtk_widget_queue_clear (widget);
3036 /*****************************************
3037 * gtk_widget_set_parent:
3042 *****************************************/
3045 gtk_widget_set_parent (GtkWidget *widget,
3050 g_return_if_fail (widget != NULL);
3051 g_return_if_fail (GTK_IS_WIDGET (widget));
3052 g_return_if_fail (widget->parent == NULL);
3053 g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
3054 g_return_if_fail (parent != NULL);
3055 g_return_if_fail (GTK_IS_WIDGET (parent));
3056 g_return_if_fail (widget != parent);
3058 /* keep this function in sync with gtk_menu_attach_to_widget()
3061 gtk_widget_ref (widget);
3062 gtk_object_sink (GTK_OBJECT (widget));
3063 widget->parent = parent;
3065 if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL)
3066 data.state = GTK_WIDGET_STATE (parent);
3068 data.state = GTK_WIDGET_STATE (widget);
3069 data.state_restoration = FALSE;
3070 data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (parent) != FALSE);
3071 data.use_forall = GTK_WIDGET_IS_SENSITIVE (parent) != GTK_WIDGET_IS_SENSITIVE (widget);
3073 gtk_widget_propagate_state (widget, &data);
3075 gtk_widget_set_style_recurse (widget, NULL);
3077 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[PARENT_SET], NULL);
3080 /*****************************************
3082 * see docs/styles.txt
3083 *****************************************/
3085 gtk_widget_set_style (GtkWidget *widget,
3088 GtkStyle *default_style;
3089 gboolean initial_emission;
3091 g_return_if_fail (widget != NULL);
3092 g_return_if_fail (GTK_IS_WIDGET (widget));
3093 g_return_if_fail (style != NULL);
3095 initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3097 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
3098 GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
3100 default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3103 gtk_style_ref (widget->style);
3104 if (!saved_default_style_key_id)
3105 saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
3106 gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
3109 gtk_widget_set_style_internal (widget, style, initial_emission);
3113 gtk_widget_ensure_style (GtkWidget *widget)
3115 g_return_if_fail (widget != NULL);
3116 g_return_if_fail (GTK_IS_WIDGET (widget));
3118 if (!GTK_WIDGET_USER_STYLE (widget) &&
3119 !GTK_WIDGET_RC_STYLE (widget))
3120 gtk_widget_set_rc_style (widget);
3124 gtk_widget_set_rc_style (GtkWidget *widget)
3126 GtkStyle *saved_style;
3127 GtkStyle *new_style;
3128 gboolean initial_emission;
3130 g_return_if_fail (widget != NULL);
3131 g_return_if_fail (GTK_IS_WIDGET (widget));
3133 initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
3135 GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3136 GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
3138 saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3139 new_style = gtk_rc_get_style (widget);
3144 gtk_style_ref (widget->style);
3145 if (!saved_default_style_key_id)
3146 saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
3147 gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
3149 gtk_widget_set_style_internal (widget, new_style, initial_emission);
3155 g_assert (initial_emission == FALSE); /* FIXME: remove this line */
3157 gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3158 gtk_widget_set_style_internal (widget, saved_style, initial_emission);
3159 gtk_style_unref (saved_style);
3163 if (initial_emission)
3164 gtk_widget_set_style_internal (widget, widget->style, TRUE);
3170 gtk_widget_restore_default_style (GtkWidget *widget)
3172 GtkStyle *default_style;
3174 g_return_if_fail (widget != NULL);
3175 g_return_if_fail (GTK_IS_WIDGET (widget));
3177 GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
3179 default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3182 gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
3183 gtk_widget_set_style_internal (widget, default_style, FALSE);
3184 gtk_style_unref (default_style);
3189 gtk_widget_get_style (GtkWidget *widget)
3191 g_return_val_if_fail (widget != NULL, NULL);
3192 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3194 return widget->style;
3198 gtk_widget_modify_style (GtkWidget *widget,
3201 GtkRcStyle *old_style;
3203 if (!rc_style_key_id)
3204 rc_style_key_id = g_quark_from_static_string (rc_style_key);
3206 old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), rc_style_key_id);
3208 if (style != old_style)
3209 gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
3212 (GtkDestroyNotify)gtk_rc_style_unref);
3216 gtk_widget_style_set (GtkWidget *widget,
3217 GtkStyle *previous_style)
3219 if (GTK_WIDGET_REALIZED (widget) &&
3220 !GTK_WIDGET_NO_WINDOW (widget))
3222 gtk_style_set_background (widget->style, widget->window, widget->state);
3223 if (GTK_WIDGET_DRAWABLE (widget))
3224 gdk_window_clear (widget->window);
3229 gtk_widget_set_style_internal (GtkWidget *widget,
3231 gboolean initial_emission)
3233 g_return_if_fail (widget != NULL);
3234 g_return_if_fail (GTK_IS_WIDGET (widget));
3235 g_return_if_fail (style != NULL);
3237 if (widget->style != style)
3239 GtkStyle *previous_style;
3241 if (GTK_WIDGET_REALIZED (widget))
3242 gtk_reset_widget_shapes(widget);
3243 if (GTK_WIDGET_REALIZED (widget))
3244 gtk_style_detach (widget->style);
3246 previous_style = widget->style;
3247 widget->style = style;
3248 gtk_style_ref (widget->style);
3250 if (GTK_WIDGET_REALIZED (widget))
3251 widget->style = gtk_style_attach (widget->style, widget->window);
3253 gtk_signal_emit (GTK_OBJECT (widget),
3254 widget_signals[STYLE_SET],
3255 initial_emission ? NULL : previous_style);
3256 gtk_style_unref (previous_style);
3258 if (widget->parent && !initial_emission)
3260 GtkRequisition old_requisition;
3262 old_requisition = widget->requisition;
3263 gtk_widget_size_request (widget, &widget->requisition);
3265 if ((old_requisition.width != widget->requisition.width) ||
3266 (old_requisition.height != widget->requisition.height))
3267 gtk_widget_queue_resize (widget);
3268 else if (GTK_WIDGET_DRAWABLE (widget))
3269 gtk_widget_queue_clear (widget);
3272 else if (initial_emission)
3274 gtk_signal_emit (GTK_OBJECT (widget),
3275 widget_signals[STYLE_SET],
3281 gtk_widget_set_style_recurse (GtkWidget *widget,
3282 gpointer client_data)
3284 if (GTK_WIDGET_RC_STYLE (widget))
3285 gtk_widget_set_rc_style (widget);
3287 if (GTK_IS_CONTAINER (widget))
3288 gtk_container_forall (GTK_CONTAINER (widget),
3289 gtk_widget_set_style_recurse,
3294 gtk_widget_reset_rc_styles (GtkWidget *widget)
3296 g_return_if_fail (widget != NULL);
3297 g_return_if_fail (GTK_IS_WIDGET (widget));
3299 gtk_widget_set_style_recurse (widget, NULL);
3303 gtk_widget_set_default_style (GtkStyle *style)
3305 if (style != gtk_default_style)
3307 if (gtk_default_style)
3308 gtk_style_unref (gtk_default_style);
3309 gtk_default_style = style;
3310 if (gtk_default_style)
3311 gtk_style_ref (gtk_default_style);
3316 gtk_widget_get_default_style (void)
3318 if (!gtk_default_style)
3320 gtk_default_style = gtk_style_new ();
3321 gtk_style_ref (gtk_default_style);
3324 return gtk_default_style;
3328 gtk_widget_push_style (GtkStyle *style)
3330 g_return_if_fail (style != NULL);
3332 gtk_style_ref (style);
3333 style_stack = g_slist_prepend (style_stack, style);
3337 gtk_widget_peek_style (void)
3340 return (GtkStyle*) style_stack->data;
3342 return gtk_widget_get_default_style ();
3346 gtk_widget_pop_style (void)
3353 style_stack = style_stack->next;
3354 gtk_style_unref ((GtkStyle*) tmp->data);
3355 g_slist_free_1 (tmp);
3359 /*************************************************************
3360 * gtk_widget_set_parent_window:
3361 * Set a non default parent window for widget
3368 *************************************************************/
3371 gtk_widget_set_parent_window (GtkWidget *widget,
3372 GdkWindow *parent_window)
3374 GdkWindow *old_parent_window;
3376 g_return_if_fail (widget != NULL);
3377 g_return_if_fail (GTK_IS_WIDGET (widget));
3379 old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3380 parent_window_key_id);
3382 if (parent_window != old_parent_window)
3384 if (!parent_window_key_id)
3385 parent_window_key_id = g_quark_from_static_string (parent_window_key);
3386 gtk_object_set_data_by_id (GTK_OBJECT (widget), parent_window_key_id,
3388 if (old_parent_window)
3389 gdk_window_unref (old_parent_window);
3391 gdk_window_ref (parent_window);
3395 /*************************************************************
3396 * gtk_widget_get_parent_window:
3397 * Get widget's parent window
3404 *************************************************************/
3407 gtk_widget_get_parent_window (GtkWidget *widget)
3409 GdkWindow *parent_window;
3411 g_return_val_if_fail (widget != NULL, NULL);
3412 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3413 g_return_val_if_fail (widget->parent != NULL, NULL);
3415 parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
3416 parent_window_key_id);
3418 return (parent_window != NULL) ? parent_window : widget->parent->window;
3421 /*****************************************
3422 * gtk_widget_set_uposition:
3427 *****************************************/
3430 gtk_widget_set_uposition (GtkWidget *widget,
3434 GtkWidgetAuxInfo *aux_info;
3436 g_return_if_fail (widget != NULL);
3437 g_return_if_fail (GTK_IS_WIDGET (widget));
3439 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3442 if (!aux_info_key_id)
3443 aux_info_key_id = g_quark_from_static_string (aux_info_key);
3444 aux_info = gtk_widget_aux_info_new ();
3445 gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3453 if (GTK_WIDGET_REALIZED (widget) && GTK_IS_WINDOW (widget) &&
3454 (aux_info->x != -1) && (aux_info->y != -1))
3456 gdk_window_set_hints (widget->window, aux_info->x, aux_info->y, 0, 0, 0, 0, GDK_HINT_POS);
3457 gdk_window_move (widget->window, aux_info->x, aux_info->y);
3460 if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
3461 gtk_widget_size_allocate (widget, &widget->allocation);
3464 /*****************************************
3465 * gtk_widget_set_usize:
3470 *****************************************/
3473 gtk_widget_set_usize (GtkWidget *widget,
3477 GtkWidgetAuxInfo *aux_info;
3479 g_return_if_fail (widget != NULL);
3480 g_return_if_fail (GTK_IS_WIDGET (widget));
3482 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
3485 if (!aux_info_key_id)
3486 aux_info_key_id = g_quark_from_static_string (aux_info_key);
3487 aux_info = gtk_widget_aux_info_new ();
3488 gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
3492 aux_info->width = width;
3494 aux_info->height = height;
3496 if (GTK_WIDGET_VISIBLE (widget))
3497 gtk_widget_queue_resize (widget);
3500 /*****************************************
3501 * gtk_widget_set_events:
3506 *****************************************/
3509 gtk_widget_set_events (GtkWidget *widget,
3514 g_return_if_fail (widget != NULL);
3515 g_return_if_fail (GTK_IS_WIDGET (widget));
3516 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3517 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
3519 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3524 eventp = g_new (gint, 1);
3528 event_key_id = g_quark_from_static_string (event_key);
3529 gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3534 gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3538 /*****************************************
3539 * gtk_widget_add_events:
3544 *****************************************/
3547 gtk_widget_add_events (GtkWidget *widget,
3552 g_return_if_fail (widget != NULL);
3553 g_return_if_fail (GTK_IS_WIDGET (widget));
3554 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
3556 eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3562 eventp = g_new (gint, 1);
3568 event_key_id = g_quark_from_static_string (event_key);
3569 gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
3574 gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
3577 if (GTK_WIDGET_REALIZED (widget))
3579 gdk_window_set_events (widget->window,
3580 gdk_window_get_events (widget->window) | events);
3584 /*****************************************
3585 * gtk_widget_set_extension_events:
3590 *****************************************/
3593 gtk_widget_set_extension_events (GtkWidget *widget,
3594 GdkExtensionMode mode)
3596 GdkExtensionMode *modep;
3598 g_return_if_fail (widget != NULL);
3599 g_return_if_fail (GTK_IS_WIDGET (widget));
3601 modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3604 modep = g_new (GdkExtensionMode, 1);
3607 if (!extension_event_key_id)
3608 extension_event_key_id = g_quark_from_static_string (extension_event_key);
3609 gtk_object_set_data_by_id (GTK_OBJECT (widget), extension_event_key_id, modep);
3612 /*****************************************
3613 * gtk_widget_get_toplevel:
3618 *****************************************/
3621 gtk_widget_get_toplevel (GtkWidget *widget)
3623 g_return_val_if_fail (widget != NULL, NULL);
3624 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3626 while (widget->parent)
3627 widget = widget->parent;
3632 /*****************************************
3633 * gtk_widget_get_ancestor:
3638 *****************************************/
3641 gtk_widget_get_ancestor (GtkWidget *widget,
3642 GtkType widget_type)
3644 g_return_val_if_fail (widget != NULL, NULL);
3645 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3647 while (widget && !gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type))
3648 widget = widget->parent;
3650 if (!(widget && gtk_type_is_a (GTK_WIDGET_TYPE (widget), widget_type)))
3656 /*****************************************
3657 * gtk_widget_get_colormap:
3662 *****************************************/
3665 gtk_widget_get_colormap (GtkWidget *widget)
3667 GdkColormap *colormap;
3669 g_return_val_if_fail (widget != NULL, NULL);
3670 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3674 colormap = gdk_window_get_colormap (widget->window);
3675 /* If window was destroyed previously, we'll get NULL here */
3680 colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
3684 return gtk_widget_get_default_colormap ();
3687 /*****************************************
3688 * gtk_widget_get_visual:
3693 *****************************************/
3696 gtk_widget_get_visual (GtkWidget *widget)
3700 g_return_val_if_fail (widget != NULL, NULL);
3701 g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
3705 visual = gdk_window_get_visual (widget->window);
3706 /* If window was destroyed previously, we'll get NULL here */
3711 visual = gtk_object_get_data (GTK_OBJECT (widget), visual_key);
3715 return gtk_widget_get_default_visual ();
3718 /*****************************************
3719 * gtk_widget_get_events:
3724 *****************************************/
3727 gtk_widget_get_events (GtkWidget *widget)
3731 g_return_val_if_fail (widget != NULL, 0);
3732 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3734 events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
3741 /*****************************************
3742 * gtk_widget_get_extension_events:
3747 *****************************************/
3750 gtk_widget_get_extension_events (GtkWidget *widget)
3752 GdkExtensionMode *mode;
3754 g_return_val_if_fail (widget != NULL, 0);
3755 g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
3757 mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
3764 /*****************************************
3765 * gtk_widget_get_pointer:
3770 *****************************************/
3773 gtk_widget_get_pointer (GtkWidget *widget,
3777 g_return_if_fail (widget != NULL);
3778 g_return_if_fail (GTK_IS_WIDGET (widget));
3785 if (GTK_WIDGET_REALIZED (widget))
3787 gdk_window_get_pointer (widget->window, x, y, NULL);
3789 if (GTK_WIDGET_NO_WINDOW (widget))
3792 *x -= widget->allocation.x;
3794 *y -= widget->allocation.y;
3799 /*****************************************
3800 * gtk_widget_is_ancestor:
3805 *****************************************/
3808 gtk_widget_is_ancestor (GtkWidget *widget,
3809 GtkWidget *ancestor)
3811 g_return_val_if_fail (widget != NULL, FALSE);
3812 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3813 g_return_val_if_fail (ancestor != NULL, FALSE);
3817 if (widget->parent == ancestor)
3819 widget = widget->parent;
3825 /*****************************************
3826 * gtk_widget_is_child:
3831 *****************************************/
3834 gtk_widget_is_child (GtkWidget *widget,
3837 g_return_val_if_fail (widget != NULL, FALSE);
3838 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3839 g_return_val_if_fail (child != NULL, FALSE);
3840 g_return_val_if_fail (GTK_IS_WIDGET (child), FALSE);
3842 return (child->parent == widget);
3845 /*****************************************
3846 * gtk_widget_push_colormap:
3851 *****************************************/
3854 gtk_widget_push_colormap (GdkColormap *cmap)
3856 g_return_if_fail (cmap != NULL);
3858 colormap_stack = g_slist_prepend (colormap_stack, cmap);
3861 /*****************************************
3862 * gtk_widget_push_visual:
3867 *****************************************/
3870 gtk_widget_push_visual (GdkVisual *visual)
3872 g_return_if_fail (visual != NULL);
3874 visual_stack = g_slist_prepend (visual_stack, visual);
3878 gtk_widget_push_composite (void)
3880 composite_child_stack++;
3884 gtk_widget_pop_composite (void)
3886 if (composite_child_stack)
3887 composite_child_stack--;
3890 /*****************************************
3891 * gtk_widget_pop_colormap:
3896 *****************************************/
3899 gtk_widget_pop_colormap (void)
3905 tmp = colormap_stack;
3906 colormap_stack = colormap_stack->next;
3907 g_slist_free_1 (tmp);
3911 /*****************************************
3912 * gtk_widget_pop_visual:
3917 *****************************************/
3920 gtk_widget_pop_visual (void)
3927 visual_stack = visual_stack->next;
3928 g_slist_free_1 (tmp);
3932 /*****************************************
3933 * gtk_widget_set_default_colormap:
3938 *****************************************/
3941 gtk_widget_set_default_colormap (GdkColormap *colormap)
3943 if (default_colormap != colormap)
3945 if (default_colormap)
3946 gdk_colormap_unref (default_colormap);
3947 default_colormap = colormap;
3948 if (default_colormap)
3949 gdk_colormap_ref (default_colormap);
3953 /*****************************************
3954 * gtk_widget_set_default_visual:
3959 *****************************************/
3962 gtk_widget_set_default_visual (GdkVisual *visual)
3964 default_visual = visual;
3967 /*****************************************
3968 * gtk_widget_get_default_colormap:
3973 *****************************************/
3976 gtk_widget_get_default_colormap (void)
3978 if (!default_colormap)
3979 default_colormap = gdk_colormap_get_system ();
3981 return default_colormap;
3984 /*****************************************
3985 * gtk_widget_get_default_visual:
3990 *****************************************/
3993 gtk_widget_get_default_visual (void)
3995 if (!default_visual)
3996 default_visual = gdk_visual_get_system ();
3998 return default_visual;
4002 gtk_widget_shutdown (GtkObject *object)
4006 /* gtk_object_destroy() will already hold a refcount on object
4008 widget = GTK_WIDGET (object);
4011 gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
4013 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4014 if (GTK_WIDGET_REALIZED (widget))
4015 gtk_widget_unrealize (widget);
4017 parent_class->shutdown (object);
4021 gtk_widget_real_destroy (GtkObject *object)
4024 GtkStyle *saved_style;
4026 /* gtk_object_destroy() will already hold a refcount on object
4028 widget = GTK_WIDGET (object);
4030 gtk_grab_remove (widget);
4031 gtk_selection_remove_all (widget);
4033 saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id);
4036 gtk_style_unref (saved_style);
4037 gtk_object_remove_data_by_id (object, saved_default_style_key_id);
4040 gtk_style_unref (widget->style);
4041 widget->style = NULL;
4043 parent_class->destroy (object);
4047 gtk_widget_finalize (GtkObject *object)
4050 GtkWidgetAuxInfo *aux_info;
4052 GdkExtensionMode *mode;
4054 widget = GTK_WIDGET (object);
4057 g_free (widget->name);
4059 aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
4061 gtk_widget_aux_info_destroy (aux_info);
4063 events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
4067 mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
4071 parent_class->finalize (object);
4074 /*****************************************
4075 * gtk_widget_real_show:
4080 *****************************************/
4083 gtk_widget_real_show (GtkWidget *widget)
4085 g_return_if_fail (widget != NULL);
4086 g_return_if_fail (GTK_IS_WIDGET (widget));
4088 if (!GTK_WIDGET_VISIBLE (widget))
4090 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4094 gtk_widget_queue_resize (widget->parent);
4096 if (GTK_WIDGET_MAPPED (widget->parent))
4097 gtk_widget_map (widget);
4102 /*****************************************
4103 * gtk_widget_real_hide:
4108 *****************************************/
4111 gtk_widget_real_hide (GtkWidget *widget)
4113 g_return_if_fail (widget != NULL);
4114 g_return_if_fail (GTK_IS_WIDGET (widget));
4116 if (GTK_WIDGET_VISIBLE (widget))
4118 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4120 if (GTK_WIDGET_MAPPED (widget))
4121 gtk_widget_unmap (widget);
4124 gtk_widget_queue_resize (widget->parent);
4128 /*****************************************
4129 * gtk_widget_real_map:
4134 *****************************************/
4137 gtk_widget_real_map (GtkWidget *widget)
4139 g_return_if_fail (widget != NULL);
4140 g_return_if_fail (GTK_IS_WIDGET (widget));
4142 if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_MAPPED (widget))
4144 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4146 if (!GTK_WIDGET_NO_WINDOW (widget))
4147 gdk_window_show (widget->window);
4149 gtk_widget_queue_draw (widget);
4153 /*****************************************
4154 * gtk_widget_real_unmap:
4159 *****************************************/
4162 gtk_widget_real_unmap (GtkWidget *widget)
4164 g_return_if_fail (widget != NULL);
4165 g_return_if_fail (GTK_IS_WIDGET (widget));
4167 if (GTK_WIDGET_MAPPED (widget))
4169 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4171 if (GTK_WIDGET_NO_WINDOW (widget))
4172 gtk_widget_queue_clear (widget);
4174 gdk_window_hide (widget->window);
4178 /*****************************************
4179 * gtk_widget_real_realize:
4184 *****************************************/
4187 gtk_widget_real_realize (GtkWidget *widget)
4189 g_return_if_fail (widget != NULL);
4190 g_return_if_fail (GTK_IS_WIDGET (widget));
4191 g_return_if_fail (GTK_WIDGET_NO_WINDOW (widget));
4193 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4196 widget->window = gtk_widget_get_parent_window (widget);
4197 gdk_window_ref (widget->window);
4199 widget->style = gtk_style_attach (widget->style, widget->window);
4202 /*****************************************
4203 * gtk_widget_real_unrealize:
4208 *****************************************/
4211 gtk_widget_real_unrealize (GtkWidget *widget)
4213 g_return_if_fail (widget != NULL);
4214 g_return_if_fail (GTK_IS_WIDGET (widget));
4216 if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_MAPPED (widget))
4217 gtk_widget_real_unmap (widget);
4219 GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
4221 /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT(widget)->klass->type));
4224 gtk_style_detach (widget->style);
4225 if (!GTK_WIDGET_NO_WINDOW (widget))
4227 gdk_window_set_user_data (widget->window, NULL);
4228 gdk_window_destroy (widget->window);
4229 widget->window = NULL;
4233 gdk_window_unref (widget->window);
4234 widget->window = NULL;
4237 /* Unrealize afterwards to improve visual effect */
4239 if (GTK_IS_CONTAINER (widget))
4240 gtk_container_forall (GTK_CONTAINER (widget),
4241 (GtkCallback) gtk_widget_unrealize,
4245 /*****************************************
4246 * gtk_widget_real_draw:
4251 *****************************************/
4254 gtk_widget_real_draw (GtkWidget *widget,
4257 GdkEventExpose event;
4259 g_return_if_fail (widget != NULL);
4260 g_return_if_fail (GTK_IS_WIDGET (widget));
4261 g_return_if_fail (area != NULL);
4263 if (GTK_WIDGET_DRAWABLE (widget))
4265 event.type = GDK_EXPOSE;
4266 event.send_event = TRUE;
4267 event.window = widget->window;
4271 gdk_window_ref (event.window);
4272 gtk_widget_event (widget, (GdkEvent*) &event);
4273 gdk_window_unref (event.window);
4278 gtk_widget_real_size_request (GtkWidget *widget,
4279 GtkRequisition *requisition)
4281 g_return_if_fail (widget != NULL);
4282 g_return_if_fail (GTK_IS_WIDGET (widget));
4284 requisition->width = widget->requisition.width;
4285 requisition->height = widget->requisition.height;
4289 gtk_widget_real_size_allocate (GtkWidget *widget,
4290 GtkAllocation *allocation)
4292 g_return_if_fail (widget != NULL);
4293 g_return_if_fail (GTK_IS_WIDGET (widget));
4295 if (GTK_WIDGET_NO_WINDOW (widget) &&
4296 GTK_WIDGET_MAPPED (widget) &&
4297 ((widget->allocation.x != allocation->x) ||
4298 (widget->allocation.y != allocation->y) ||
4299 (widget->allocation.width != allocation->width) ||
4300 (widget->allocation.height != allocation->height)) &&
4301 (widget->allocation.width != 0) &&
4302 (widget->allocation.height != 0))
4303 gtk_widget_queue_clear (widget);
4305 widget->allocation = *allocation;
4307 if (GTK_WIDGET_REALIZED (widget) &&
4308 !GTK_WIDGET_NO_WINDOW (widget))
4310 gdk_window_move_resize (widget->window,
4311 allocation->x, allocation->y,
4312 allocation->width, allocation->height);
4316 /*****************************************
4317 * gtk_widget_peek_colormap:
4322 *****************************************/
4325 gtk_widget_peek_colormap (void)
4328 return (GdkColormap*) colormap_stack->data;
4329 return gtk_widget_get_default_colormap ();
4332 /*****************************************
4333 * gtk_widget_peek_visual:
4338 *****************************************/
4341 gtk_widget_peek_visual (void)
4344 return (GdkVisual*) visual_stack->data;
4345 return gtk_widget_get_default_visual ();
4349 gtk_widget_propagate_state (GtkWidget *widget,
4354 /* don't call this function with state==GTK_STATE_INSENSITIVE,
4355 * parent_sensitive==TRUE on a sensitive widget
4358 old_state = GTK_WIDGET_STATE (widget);
4360 if (data->parent_sensitive)
4362 GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4364 if (GTK_WIDGET_IS_SENSITIVE (widget))
4366 if (data->state_restoration)
4367 GTK_WIDGET_STATE (widget) = GTK_WIDGET_SAVED_STATE (widget);
4369 GTK_WIDGET_STATE (widget) = data->state;
4373 GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4374 if (!data->state_restoration &&
4375 data->state != GTK_STATE_INSENSITIVE)
4376 GTK_WIDGET_SAVED_STATE (widget) = data->state;
4381 GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
4382 if (!data->state_restoration)
4384 if (data->state != GTK_STATE_INSENSITIVE)
4385 GTK_WIDGET_SAVED_STATE (widget) = data->state;
4387 else if (GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE)
4388 GTK_WIDGET_SAVED_STATE (widget) = GTK_WIDGET_STATE (widget);
4389 GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
4392 if (GTK_WIDGET_HAS_FOCUS (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
4396 window = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
4398 gtk_window_set_focus (GTK_WINDOW (window), NULL);
4401 if (old_state != GTK_WIDGET_STATE (widget))
4403 gtk_widget_ref (widget);
4404 gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED], old_state);
4406 if (GTK_IS_CONTAINER (widget))
4408 data->parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget) != FALSE);
4409 data->state = GTK_WIDGET_STATE (widget);
4410 if (data->use_forall)
4411 gtk_container_forall (GTK_CONTAINER (widget),
4412 (GtkCallback) gtk_widget_propagate_state,
4415 gtk_container_foreach (GTK_CONTAINER (widget),
4416 (GtkCallback) gtk_widget_propagate_state,
4419 gtk_widget_unref (widget);
4423 /*****************************************
4424 * gtk_widget_draw_children_recurse:
4429 *****************************************/
4432 gtk_widget_draw_children_recurse (GtkWidget *widget,
4433 gpointer client_data)
4435 gtk_widget_draw (widget, NULL);
4436 gtk_widget_draw_children (widget);
4439 /*****************************************
4440 * gtk_widget_aux_info_new:
4445 *****************************************/
4447 static GtkWidgetAuxInfo*
4448 gtk_widget_aux_info_new (void)
4450 GtkWidgetAuxInfo *aux_info;
4452 if (!aux_info_mem_chunk)
4453 aux_info_mem_chunk = g_mem_chunk_new ("widget aux info mem chunk",
4454 sizeof (GtkWidgetAuxInfo),
4455 1024, G_ALLOC_AND_FREE);
4457 aux_info = g_chunk_new (GtkWidgetAuxInfo, aux_info_mem_chunk);
4461 aux_info->width = 0;
4462 aux_info->height = 0;
4467 /*****************************************
4468 * gtk_widget_aux_info_destroy:
4473 *****************************************/
4476 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
4478 g_return_if_fail (aux_info != NULL);
4480 g_mem_chunk_free (aux_info_mem_chunk, aux_info);
4483 /*****************************************
4484 * gtk_widget_shape_combine_mask:
4485 * set a shape for this widgets' gdk window, this allows for
4486 * transparent windows etc., see gdk_window_shape_combine_mask
4487 * for more information
4492 *****************************************/
4494 gtk_widget_shape_combine_mask (GtkWidget *widget,
4495 GdkBitmap *shape_mask,
4499 GtkWidgetShapeInfo* shape_info;
4501 g_return_if_fail (widget != NULL);
4502 g_return_if_fail (GTK_IS_WIDGET (widget));
4503 /* set_shape doesn't work on widgets without gdk window */
4504 g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
4508 GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4511 gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
4513 shape_info = gtk_object_get_data (GTK_OBJECT (widget), shape_info_key);
4514 gtk_object_remove_data (GTK_OBJECT (widget), shape_info_key);
4515 g_free (shape_info);
4519 GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
4521 shape_info = gtk_object_get_data (GTK_OBJECT (widget), shape_info_key);
4524 shape_info = g_new (GtkWidgetShapeInfo, 1);
4525 gtk_object_set_data (GTK_OBJECT (widget), shape_info_key, shape_info);
4527 shape_info->shape_mask = shape_mask;
4528 shape_info->offset_x = offset_x;
4529 shape_info->offset_y = offset_y;
4531 /* set shape if widget has a gdk window allready.
4532 * otherwise the shape is scheduled to be set by gtk_widget_realize.
4535 gdk_window_shape_combine_mask (widget->window, shape_mask,
4536 offset_x, offset_y);
4541 gtk_widget_ref (GtkWidget *widget)
4543 g_return_if_fail (widget != NULL);
4544 g_return_if_fail (GTK_IS_WIDGET (widget));
4546 gtk_object_ref ((GtkObject*) widget);
4550 gtk_widget_unref (GtkWidget *widget)
4552 g_return_if_fail (widget != NULL);
4553 g_return_if_fail (GTK_IS_WIDGET (widget));
4555 gtk_object_unref ((GtkObject*) widget);
4559 gtk_widget_path (GtkWidget *widget,
4560 guint *path_length_p,
4562 gchar **path_reversed_p)
4564 static gchar *rev_path = NULL;
4565 static guint path_len = 0;
4568 g_return_if_fail (widget != NULL);
4569 g_return_if_fail (GTK_IS_WIDGET (widget));
4578 string = gtk_widget_get_name (widget);
4579 l = strlen (string);
4580 while (path_len <= len + l + 1)
4582 path_len += INIT_PATH_SIZE;
4583 rev_path = g_realloc (rev_path, path_len);
4591 widget = widget->parent;
4594 rev_path[len++] = '.';
4596 rev_path[len++] = 0;
4601 *path_length_p = len - 1;
4602 if (path_reversed_p)
4603 *path_reversed_p = g_strdup (rev_path);
4606 *path_p = g_strdup (rev_path);
4607 g_strreverse (*path_p);
4612 gtk_widget_class_path (GtkWidget *widget,
4613 guint *path_length_p,
4615 gchar **path_reversed_p)
4617 static gchar *rev_path = NULL;
4618 static guint path_len = 0;
4621 g_return_if_fail (widget != NULL);
4622 g_return_if_fail (GTK_IS_WIDGET (widget));
4631 string = gtk_type_name (GTK_WIDGET_TYPE (widget));
4632 l = strlen (string);
4633 while (path_len <= len + l + 1)
4635 path_len += INIT_PATH_SIZE;
4636 rev_path = g_realloc (rev_path, path_len);
4644 widget = widget->parent;
4647 rev_path[len++] = '.';
4649 rev_path[len++] = 0;
4654 *path_length_p = len - 1;
4655 if (path_reversed_p)
4656 *path_reversed_p = g_strdup (rev_path);
4659 *path_p = g_strdup (rev_path);
4660 g_strreverse (*path_p);