1
/* GTK - The GIMP Toolkit
2
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with this library; if not, write to the
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 * Boston, MA 02111-1307, USA.
18
 */
19
20
/*
21
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22
 * file for a list of people on the GTK+ Team.  See the ChangeLog
23
 * files for a list of changes.  These files are distributed with
24
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25
 */
26
27
#include "config.h"
28
#include <stdarg.h>
29
#include <string.h>
30
#include <locale.h>
31
#include "gtkcontainer.h"
32
#include "gtkaccelmap.h"
33
#include "gtkclipboard.h"
34
#include "gtkiconfactory.h"
35
#include "gtkintl.h"
36
#include "gtkmain.h"
37
#include "gtkmarshalers.h"
38
#include "gtkrc.h"
39
#include "gtkselection.h"
40
#include "gtksettings.h"
41
#include "gtksizegroup.h"
42
#include "gtkwidget.h"
43
#include "gtkwindow.h"
44
#include "gtkbindings.h"
45
#include "gtkprivate.h"
46
#include "gdk/gdk.h"
47
#include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
48
#include <gobject/gvaluecollector.h>
49
#include <gobject/gobjectnotifyqueue.c>
50
#include "gdk/gdkkeysyms.h"
51
#include "gtkaccessible.h"
52
#include "gtktooltip.h"
53
#include "gtkinvisible.h"
54
#include "gtkbuildable.h"
55
#include "gtkbuilderprivate.h"
56
#include "gtkalias.h"
57
#ifdef MAEMO_CHANGES
58
#include <x11/gdkx.h>
59
#include <stdlib.h>
60
#include "gtkmenu.h"
61
#include "gtkmenuitem.h"
62
#include "gtkicontheme.h"
63
#include "gtkdnd.h"
64
#endif /* MAEMO_CHANGES */
65
66
#define WIDGET_CLASS(w)	 GTK_WIDGET_GET_CLASS (w)
67
#define	INIT_PATH_SIZE	(512)
68
69
#ifdef MAEMO_CHANGES
70
#define TAP_AND_HOLD_TIMER_COUNTER 6
71
#define TAP_AND_HOLD_TIMER_INTERVAL 100
72
73
/* #define TAP_AND_HOLD_ANIMATION 1 */
74
#endif /* MAEMO_CHANGES */
75
76
enum {
77
  SHOW,
78
  HIDE,
79
  MAP,
80
  UNMAP,
81
  REALIZE,
82
  UNREALIZE,
83
  SIZE_REQUEST,
84
  SIZE_ALLOCATE,
85
  STATE_CHANGED,
86
  PARENT_SET,
87
  HIERARCHY_CHANGED,
88
  STYLE_SET,
89
  DIRECTION_CHANGED,
90
  GRAB_NOTIFY,
91
  CHILD_NOTIFY,
92
  MNEMONIC_ACTIVATE,
93
  GRAB_FOCUS,
94
  FOCUS,
95
  MOVE_FOCUS,
96
  EVENT,
97
  EVENT_AFTER,
98
  BUTTON_PRESS_EVENT,
99
  BUTTON_RELEASE_EVENT,
100
  SCROLL_EVENT,
101
  MOTION_NOTIFY_EVENT,
102
  DELETE_EVENT,
103
  DESTROY_EVENT,
104
  EXPOSE_EVENT,
105
  KEY_PRESS_EVENT,
106
  KEY_RELEASE_EVENT,
107
  ENTER_NOTIFY_EVENT,
108
  LEAVE_NOTIFY_EVENT,
109
  CONFIGURE_EVENT,
110
  FOCUS_IN_EVENT,
111
  FOCUS_OUT_EVENT,
112
  MAP_EVENT,
113
  UNMAP_EVENT,
114
  PROPERTY_NOTIFY_EVENT,
115
  SELECTION_CLEAR_EVENT,
116
  SELECTION_REQUEST_EVENT,
117
  SELECTION_NOTIFY_EVENT,
118
  SELECTION_GET,
119
  SELECTION_RECEIVED,
120
  PROXIMITY_IN_EVENT,
121
  PROXIMITY_OUT_EVENT,
122
  DRAG_BEGIN,
123
  DRAG_END,
124
  DRAG_DATA_DELETE,
125
  DRAG_LEAVE,
126
  DRAG_MOTION,
127
  DRAG_DROP,
128
  DRAG_DATA_GET,
129
  DRAG_DATA_RECEIVED,
130
  CLIENT_EVENT,
131
  NO_EXPOSE_EVENT,
132
  VISIBILITY_NOTIFY_EVENT,
133
  WINDOW_STATE_EVENT,
134
  POPUP_MENU,
135
  SHOW_HELP,
136
  ACCEL_CLOSURES_CHANGED,
137
  SCREEN_CHANGED,
138
  CAN_ACTIVATE_ACCEL,
139
  GRAB_BROKEN,
140
  COMPOSITED_CHANGED,
141
  QUERY_TOOLTIP,
142
  KEYNAV_FAILED,
143
  DRAG_FAILED,
144
  DAMAGE_EVENT,
145
#ifdef MAEMO_CHANGES
146
  INSENSITIVE_PRESS,
147
  TAP_AND_HOLD,
148
  TAP_AND_HOLD_SETUP,
149
  TAP_AND_HOLD_QUERY,
150
#endif /* MAEMO_CHANGES */
151
  LAST_SIGNAL
152
};
153
154
enum {
155
  PROP_0,
156
  PROP_NAME,
157
  PROP_PARENT,
158
  PROP_WIDTH_REQUEST,
159
  PROP_HEIGHT_REQUEST,
160
  PROP_VISIBLE,
161
  PROP_SENSITIVE,
162
  PROP_APP_PAINTABLE,
163
  PROP_CAN_FOCUS,
164
  PROP_HAS_FOCUS,
165
  PROP_IS_FOCUS,
166
  PROP_CAN_DEFAULT,
167
  PROP_HAS_DEFAULT,
168
  PROP_RECEIVES_DEFAULT,
169
  PROP_COMPOSITE_CHILD,
170
  PROP_STYLE,
171
  PROP_EVENTS,
172
  PROP_EXTENSION_EVENTS,
173
  PROP_NO_SHOW_ALL,
174
  PROP_HAS_TOOLTIP,
175
  PROP_TOOLTIP_MARKUP,
176
  PROP_TOOLTIP_TEXT,
177
  PROP_WINDOW
178
#ifdef MAEMO_CHANGES
179
  , PROP_TAP_AND_HOLD
180
#endif /* MAEMO_CHANGES */
181
};
182
183
typedef	struct	_GtkStateData	 GtkStateData;
184
185
struct _GtkStateData
186
{
187
  GtkStateType  state;
188
  guint		state_restoration : 1;
189
  guint         parent_sensitive : 1;
190
  guint		use_forall : 1;
191
};
192
193
/* --- prototypes --- */
194
static void	gtk_widget_class_init		(GtkWidgetClass     *klass);
195
static void	gtk_widget_base_class_finalize	(GtkWidgetClass     *klass);
196
static void	gtk_widget_init			(GtkWidget          *widget);
197
static void	gtk_widget_set_property		 (GObject           *object,
198
						  guint              prop_id,
199
						  const GValue      *value,
200
						  GParamSpec        *pspec);
201
static void	gtk_widget_get_property		 (GObject           *object,
202
						  guint              prop_id,
203
						  GValue            *value,
204
						  GParamSpec        *pspec);
205
static void	gtk_widget_dispose		 (GObject	    *object);
206
static void	gtk_widget_real_destroy		 (GtkObject	    *object);
207
static void	gtk_widget_finalize		 (GObject	    *object);
208
static void	gtk_widget_real_show		 (GtkWidget	    *widget);
209
static void	gtk_widget_real_hide		 (GtkWidget	    *widget);
210
static void	gtk_widget_real_map		 (GtkWidget	    *widget);
211
static void	gtk_widget_real_unmap		 (GtkWidget	    *widget);
212
static void	gtk_widget_real_realize		 (GtkWidget	    *widget);
213
static void	gtk_widget_real_unrealize	 (GtkWidget	    *widget);
214
static void	gtk_widget_real_size_request	 (GtkWidget	    *widget,
215
						  GtkRequisition    *requisition);
216
static void	gtk_widget_real_size_allocate	 (GtkWidget	    *widget,
217
						  GtkAllocation	    *allocation);
218
static void	gtk_widget_real_style_set        (GtkWidget         *widget,
219
                                                  GtkStyle          *previous_style);
220
static void	gtk_widget_real_direction_changed(GtkWidget         *widget,
221
                                                  GtkTextDirection   previous_direction);
222
223
static void	gtk_widget_real_grab_focus	 (GtkWidget         *focus_widget);
224
static gboolean gtk_widget_real_query_tooltip    (GtkWidget         *widget,
225
						  gint               x,
226
						  gint               y,
227
						  gboolean           keyboard_tip,
228
						  GtkTooltip        *tooltip);
229
static gboolean gtk_widget_real_show_help        (GtkWidget         *widget,
230
                                                  GtkWidgetHelpType  help_type);
231
232
static void	gtk_widget_dispatch_child_properties_changed	(GtkWidget        *object,
233
								 guint             n_pspecs,
234
								 GParamSpec      **pspecs);
235
static gboolean		gtk_widget_real_key_press_event   	(GtkWidget        *widget,
236
								 GdkEventKey      *event);
237
static gboolean		gtk_widget_real_key_release_event 	(GtkWidget        *widget,
238
								 GdkEventKey      *event);
239
static gboolean		gtk_widget_real_focus_in_event   	 (GtkWidget       *widget,
240
								  GdkEventFocus   *event);
241
static gboolean		gtk_widget_real_focus_out_event   	(GtkWidget        *widget,
242
								 GdkEventFocus    *event);
243
static gboolean		gtk_widget_real_focus			(GtkWidget        *widget,
244
								 GtkDirectionType  direction);
245
static void             gtk_widget_real_move_focus              (GtkWidget        *widget,
246
                                                                 GtkDirectionType  direction);
247
static gboolean		gtk_widget_real_keynav_failed		(GtkWidget        *widget,
248
								 GtkDirectionType  direction);
249
static PangoContext*	gtk_widget_peek_pango_context		(GtkWidget	  *widget);
250
static void     	gtk_widget_update_pango_context		(GtkWidget	  *widget);
251
static void		gtk_widget_propagate_state		(GtkWidget	  *widget,
252
								 GtkStateData 	  *data);
253
static void             gtk_widget_reset_rc_style               (GtkWidget        *widget);
254
static void		gtk_widget_set_style_internal		(GtkWidget	  *widget,
255
								 GtkStyle	  *style,
256
								 gboolean	   initial_emission);
257
static gint		gtk_widget_event_internal		(GtkWidget	  *widget,
258
								 GdkEvent	  *event);
259
static gboolean		gtk_widget_real_mnemonic_activate	(GtkWidget	  *widget,
260
								 gboolean	   group_cycling);
261
static void		gtk_widget_aux_info_destroy		(GtkWidgetAuxInfo *aux_info);
262
static AtkObject*	gtk_widget_real_get_accessible		(GtkWidget	  *widget);
263
static void		gtk_widget_accessible_interface_init	(AtkImplementorIface *iface);
264
static AtkObject*	gtk_widget_ref_accessible		(AtkImplementor *implementor);
265
static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
266
								 GdkRegion        *region);
267
static GdkScreen *      gtk_widget_get_screen_unchecked         (GtkWidget        *widget);
268
static void		gtk_widget_queue_shallow_draw		(GtkWidget        *widget);
269
static gboolean         gtk_widget_real_can_activate_accel      (GtkWidget *widget,
270
                                                                 guint      signal_id);
271
272
static void             gtk_widget_real_set_has_tooltip         (GtkWidget *widget,
273
								 gboolean   has_tooltip,
274
								 gboolean   force);
275
static void             gtk_widget_buildable_interface_init     (GtkBuildableIface *iface);
276
static void             gtk_widget_buildable_set_name           (GtkBuildable     *buildable,
277
                                                                 const gchar      *name);
278
static const gchar *    gtk_widget_buildable_get_name           (GtkBuildable     *buildable);
279
static GObject *        gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
280
								 GtkBuilder   *builder,
281
								 const gchar  *childname);
282
static void             gtk_widget_buildable_set_buildable_property (GtkBuildable     *buildable,
283
								     GtkBuilder       *builder,
284
								     const gchar      *name,
285
								     const GValue     *value);
286
static gboolean         gtk_widget_buildable_custom_tag_start   (GtkBuildable     *buildable,
287
                                                                 GtkBuilder       *builder,
288
                                                                 GObject          *child,
289
                                                                 const gchar      *tagname,
290
                                                                 GMarkupParser    *parser,
291
                                                                 gpointer         *data);
292
static void             gtk_widget_buildable_custom_finished    (GtkBuildable     *buildable,
293
                                                                 GtkBuilder       *builder,
294
                                                                 GObject          *child,
295
                                                                 const gchar      *tagname,
296
                                                                 gpointer          data);
297
static void             gtk_widget_buildable_parser_finished    (GtkBuildable     *buildable,
298
                                                                 GtkBuilder       *builder);
299
300
     
301
static void gtk_widget_set_usize_internal (GtkWidget *widget,
302
					   gint       width,
303
					   gint       height);
304
static void gtk_widget_get_draw_rectangle (GtkWidget    *widget,
305
					   GdkRectangle *rect);
306
307
#ifdef MAEMO_CHANGES
308
typedef struct
309
{
310
  GtkWidget *menu;
311
  guint timer_id;
312
313
  GtkMenuPositionFunc func;
314
  gint x, y;
315
  gint timer_counter;
316
  gint signals_connected : 1;
317
  guint interval;
318
  GdkWindow *tah_on_window;
319
320
#ifdef TAP_AND_HOLD_ANIMATION
321
  GdkPixbufAnimation *anim;
322
  GdkPixbufAnimationIter *iter;
323
#endif
324
} TahData;
325
326
327
/* --- Tap And Hold --- */
328
static gboolean gtk_widget_tap_and_hold_timeout           (GtkWidget                *widget);
329
static gboolean gtk_widget_tap_and_hold_button_press      (GtkWidget                *widget,
330
                                                           GdkEvent                 *event,
331
                                                           TahData                  *td);
332
static gboolean gtk_widget_tap_and_hold_event_stop        (GtkWidget                *widget,
333
                                                           gpointer                  unused,
334
                                                           TahData                  *td);
335
static void     gtk_widget_real_tap_and_hold_setup        (GtkWidget                *widget,
336
                                                           GtkWidget                *menu,
337
                                                           GtkCallback               func,
338
                                                           GtkWidgetTapAndHoldFlags  flags );
339
static void     gtk_widget_real_tap_and_hold              (GtkWidget                *widget);
340
static gboolean gtk_widget_tap_and_hold_query             (GtkWidget                *widget,
341
                                                           GdkEvent                 *event);
342
static gboolean gtk_widget_real_tap_and_hold_query        (GtkWidget                *widget,
343
                                                           GdkEvent                 *event);
344
345
static gboolean gtk_widget_tap_and_hold_query_accumulator (GSignalInvocationHint    *ihint,
346
                                                           GValue                   *return_accu,
347
                                                           const GValue             *handler_return,
348
                                                           gpointer                  dummy);
349
#endif /* MAEMO_CHANGES */
350
351
352
/* --- variables --- */
353
static gpointer         gtk_widget_parent_class = NULL;
354
static guint            widget_signals[LAST_SIGNAL] = { 0 };
355
static GtkStyle        *gtk_default_style = NULL;
356
static GSList          *colormap_stack = NULL;
357
static guint            composite_child_stack = 0;
358
static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
359
static GParamSpecPool  *style_property_spec_pool = NULL;
360
361
static GQuark		quark_property_parser = 0;
362
static GQuark		quark_aux_info = 0;
363
static GQuark		quark_accel_path = 0;
364
static GQuark		quark_accel_closures = 0;
365
static GQuark		quark_event_mask = 0;
366
static GQuark		quark_extension_event_mode = 0;
367
static GQuark		quark_parent_window = 0;
368
static GQuark		quark_pointer_window = 0;
369
static GQuark		quark_shape_info = 0;
370
static GQuark		quark_input_shape_info = 0;
371
static GQuark		quark_colormap = 0;
372
static GQuark		quark_pango_context = 0;
373
static GQuark		quark_rc_style = 0;
374
static GQuark		quark_accessible_object = 0;
375
static GQuark		quark_mnemonic_labels = 0;
376
static GQuark		quark_tooltip_markup = 0;
377
static GQuark		quark_has_tooltip = 0;
378
static GQuark		quark_tooltip_window = 0;
379
GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
380
GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
381
382
/* --- functions --- */
383
GType
384
gtk_widget_get_type (void)
385
{
386
  static GType widget_type = 0;
387
388
  if (G_UNLIKELY (widget_type == 0))
389
    {
390
      const GTypeInfo widget_info =
391
      {
392
	sizeof (GtkWidgetClass),
393
	NULL,		/* base_init */
394
	(GBaseFinalizeFunc) gtk_widget_base_class_finalize,
395
	(GClassInitFunc) gtk_widget_class_init,
396
	NULL,		/* class_finalize */
397
	NULL,		/* class_init */
398
	sizeof (GtkWidget),
399
	0,		/* n_preallocs */
400
	(GInstanceInitFunc) gtk_widget_init,
401
	NULL,		/* value_table */
402
      };
403
404
      const GInterfaceInfo accessibility_info =
405
      {
406
	(GInterfaceInitFunc) gtk_widget_accessible_interface_init,
407
	(GInterfaceFinalizeFunc) NULL,
408
	NULL /* interface data */
409
      };
410
411
      const GInterfaceInfo buildable_info =
412
      {
413
	(GInterfaceInitFunc) gtk_widget_buildable_interface_init,
414
	(GInterfaceFinalizeFunc) NULL,
415
	NULL /* interface data */
416
      };
417
418
      widget_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkWidget",
419
                                           &widget_info, G_TYPE_FLAG_ABSTRACT);
420
421
      g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
422
                                   &accessibility_info) ;
423
      g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
424
                                   &buildable_info) ;
425
426
    }
427
428
  return widget_type;
429
}
430
431
static void
432
child_property_notify_dispatcher (GObject     *object,
433
				  guint        n_pspecs,
434
				  GParamSpec **pspecs)
435
{
436
  GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs);
437
}
438
439
#ifdef MAEMO_CHANGES
440
static void
441
maemo_widget_constructed (GObject *object)
442
{
443
  static GQuark quark_maemo_widget_customizer = 0;
444
  if (!quark_maemo_widget_customizer)
445
    quark_maemo_widget_customizer = g_quark_from_static_string ("maemo_widget_customizer");
446
  void (*hook) (GtkWidget*) = g_type_get_qdata (G_OBJECT_TYPE (object), quark_maemo_widget_customizer);
447
  if (hook)
448
    hook (GTK_WIDGET (object));
449
}
450
#endif /* MAEMO_CHANGES */
451
452
static void
453
gtk_widget_class_init (GtkWidgetClass *klass)
454
{
455
  static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
456
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
457
  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
458
  GtkBindingSet *binding_set;
459
460
  gtk_widget_parent_class = g_type_class_peek_parent (klass);
461
462
  quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
463
  quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
464
  quark_accel_path = g_quark_from_static_string ("gtk-accel-path");
465
  quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures");
466
  quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
467
  quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
468
  quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
469
  quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
470
  quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
471
  quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info");
472
  quark_colormap = g_quark_from_static_string ("gtk-colormap");
473
  quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
474
  quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
475
  quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
476
  quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels");
477
  quark_tooltip_markup = g_quark_from_static_string ("gtk-tooltip-markup");
478
  quark_has_tooltip = g_quark_from_static_string ("gtk-has-tooltip");
479
  quark_tooltip_window = g_quark_from_static_string ("gtk-tooltip-window");
480
481
  style_property_spec_pool = g_param_spec_pool_new (FALSE);
482
  _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
483
  cpn_context.quark_notify_queue = g_quark_from_static_string ("GtkWidget-child-property-notify-queue");
484
  cpn_context.dispatcher = child_property_notify_dispatcher;
485
  _gtk_widget_child_property_notify_context = &cpn_context;
486
487
#ifdef MAEMO_CHANGES
488
  gobject_class->constructed = maemo_widget_constructed;
489
#endif /* MAEMO_CHANGES */
490
  gobject_class->dispose = gtk_widget_dispose;
491
  gobject_class->finalize = gtk_widget_finalize;
492
  gobject_class->set_property = gtk_widget_set_property;
493
  gobject_class->get_property = gtk_widget_get_property;
494
495
  object_class->destroy = gtk_widget_real_destroy;
496
  
497
  klass->activate_signal = 0;
498
  klass->set_scroll_adjustments_signal = 0;
499
  klass->dispatch_child_properties_changed = gtk_widget_dispatch_child_properties_changed;
500
  klass->show = gtk_widget_real_show;
501
  klass->show_all = gtk_widget_show;
502
  klass->hide = gtk_widget_real_hide;
503
  klass->hide_all = gtk_widget_hide;
504
  klass->map = gtk_widget_real_map;
505
  klass->unmap = gtk_widget_real_unmap;
506
  klass->realize = gtk_widget_real_realize;
507
  klass->unrealize = gtk_widget_real_unrealize;
508
  klass->size_request = gtk_widget_real_size_request;
509
  klass->size_allocate = gtk_widget_real_size_allocate;
510
  klass->state_changed = NULL;
511
  klass->parent_set = NULL;
512
  klass->hierarchy_changed = NULL;
513
  klass->style_set = gtk_widget_real_style_set;
514
  klass->direction_changed = gtk_widget_real_direction_changed;
515
  klass->grab_notify = NULL;
516
  klass->child_notify = NULL;
517
  klass->mnemonic_activate = gtk_widget_real_mnemonic_activate;
518
  klass->grab_focus = gtk_widget_real_grab_focus;
519
  klass->focus = gtk_widget_real_focus;
520
  klass->event = NULL;
521
  klass->button_press_event = NULL;
522
  klass->button_release_event = NULL;
523
  klass->motion_notify_event = NULL;
524
  klass->delete_event = NULL;
525
  klass->destroy_event = NULL;
526
  klass->expose_event = NULL;
527
  klass->key_press_event = gtk_widget_real_key_press_event;
528
  klass->key_release_event = gtk_widget_real_key_release_event;
529
  klass->enter_notify_event = NULL;
530
  klass->leave_notify_event = NULL;
531
  klass->configure_event = NULL;
532
  klass->focus_in_event = gtk_widget_real_focus_in_event;
533
  klass->focus_out_event = gtk_widget_real_focus_out_event;
534
  klass->map_event = NULL;
535
  klass->unmap_event = NULL;
536
  klass->window_state_event = NULL;
537
  klass->property_notify_event = _gtk_selection_property_notify;
538
  klass->selection_clear_event = gtk_selection_clear;
539
  klass->selection_request_event = _gtk_selection_request;
540
  klass->selection_notify_event = _gtk_selection_notify;
541
  klass->selection_received = NULL;
542
  klass->proximity_in_event = NULL;
543
  klass->proximity_out_event = NULL;
544
  klass->drag_begin = NULL;
545
  klass->drag_end = NULL;
546
  klass->drag_data_delete = NULL;
547
  klass->drag_leave = NULL;
548
  klass->drag_motion = NULL;
549
  klass->drag_drop = NULL;
550
  klass->drag_data_received = NULL;
551
  klass->screen_changed = NULL;
552
  klass->can_activate_accel = gtk_widget_real_can_activate_accel;
553
  klass->grab_broken_event = NULL;
554
  klass->query_tooltip = gtk_widget_real_query_tooltip;
555
556
  klass->show_help = gtk_widget_real_show_help;
557
  
558
  /* Accessibility support */
559
  klass->get_accessible = gtk_widget_real_get_accessible;
560
561
  klass->no_expose_event = NULL;
562
563
  g_object_class_install_property (gobject_class,
564
				   PROP_NAME,
565
				   g_param_spec_string ("name",
566
 							P_("Widget name"),
567
							P_("The name of the widget"),
568
							NULL,
569
							GTK_PARAM_READWRITE));
570
  g_object_class_install_property (gobject_class,
571
				   PROP_PARENT,
572
				   g_param_spec_object ("parent",
573
							P_("Parent widget"), 
574
							P_("The parent widget of this widget. Must be a Container widget"),
575
							GTK_TYPE_CONTAINER,
576
							GTK_PARAM_READWRITE));
577
578
  g_object_class_install_property (gobject_class,
579
				   PROP_WIDTH_REQUEST,
580
				   g_param_spec_int ("width-request",
581
 						     P_("Width request"),
582
 						     P_("Override for width request of the widget, or -1 if natural request should be used"),
583
 						     -1,
584
 						     G_MAXINT,
585
 						     -1,
586
 						     GTK_PARAM_READWRITE));
587
  g_object_class_install_property (gobject_class,
588
				   PROP_HEIGHT_REQUEST,
589
				   g_param_spec_int ("height-request",
590
 						     P_("Height request"),
591
 						     P_("Override for height request of the widget, or -1 if natural request should be used"),
592
 						     -1,
593
 						     G_MAXINT,
594
 						     -1,
595
 						     GTK_PARAM_READWRITE));
596
  g_object_class_install_property (gobject_class,
597
				   PROP_VISIBLE,
598
				   g_param_spec_boolean ("visible",
599
 							 P_("Visible"),
600
 							 P_("Whether the widget is visible"),
601
 							 FALSE,
602
 							 GTK_PARAM_READWRITE));
603
  g_object_class_install_property (gobject_class,
604
				   PROP_SENSITIVE,
605
				   g_param_spec_boolean ("sensitive",
606
 							 P_("Sensitive"),
607
 							 P_("Whether the widget responds to input"),
608
 							 TRUE,
609
 							 GTK_PARAM_READWRITE));
610
  g_object_class_install_property (gobject_class,
611
				   PROP_APP_PAINTABLE,
612
				   g_param_spec_boolean ("app-paintable",
613
 							 P_("Application paintable"),
614
 							 P_("Whether the application will paint directly on the widget"),
615
 							 FALSE,
616
 							 GTK_PARAM_READWRITE));
617
  g_object_class_install_property (gobject_class,
618
				   PROP_CAN_FOCUS,
619
				   g_param_spec_boolean ("can-focus",
620
 							 P_("Can focus"),
621
 							 P_("Whether the widget can accept the input focus"),
622
 							 FALSE,
623
 							 GTK_PARAM_READWRITE));
624
  g_object_class_install_property (gobject_class,
625
				   PROP_HAS_FOCUS,
626
				   g_param_spec_boolean ("has-focus",
627
 							 P_("Has focus"),
628
 							 P_("Whether the widget has the input focus"),
629
 							 FALSE,
630
 							 GTK_PARAM_READWRITE));
631
  g_object_class_install_property (gobject_class,
632
				   PROP_IS_FOCUS,
633
				   g_param_spec_boolean ("is-focus",
634
 							 P_("Is focus"),
635
 							 P_("Whether the widget is the focus widget within the toplevel"),
636
 							 FALSE,
637
 							 GTK_PARAM_READWRITE));
638
  g_object_class_install_property (gobject_class,
639
				   PROP_CAN_DEFAULT,
640
				   g_param_spec_boolean ("can-default",
641
 							 P_("Can default"),
642
 							 P_("Whether the widget can be the default widget"),
643
 							 FALSE,
644
 							 GTK_PARAM_READWRITE));
645
  g_object_class_install_property (gobject_class,
646
				   PROP_HAS_DEFAULT,
647
				   g_param_spec_boolean ("has-default",
648
 							 P_("Has default"),
649
 							 P_("Whether the widget is the default widget"),
650
 							 FALSE,
651
 							 GTK_PARAM_READWRITE));
652
  g_object_class_install_property (gobject_class,
653
				   PROP_RECEIVES_DEFAULT,
654
				   g_param_spec_boolean ("receives-default",
655
 							 P_("Receives default"),
656
 							 P_("If TRUE, the widget will receive the default action when it is focused"),
657
 							 FALSE,
658
 							 GTK_PARAM_READWRITE));
659
  g_object_class_install_property (gobject_class,
660
				   PROP_COMPOSITE_CHILD,
661
				   g_param_spec_boolean ("composite-child",
662
 							 P_("Composite child"),
663
 							 P_("Whether the widget is part of a composite widget"),
664
 							 FALSE,
665
 							 GTK_PARAM_READABLE));
666
  g_object_class_install_property (gobject_class,
667
				   PROP_STYLE,
668
				   g_param_spec_object ("style",
669
 							P_("Style"),
670
 							P_("The style of the widget, which contains information about how it will look (colors etc)"),
671
 							GTK_TYPE_STYLE,
672
 							GTK_PARAM_READWRITE));
673
  g_object_class_install_property (gobject_class,
674
				   PROP_EVENTS,
675
				   g_param_spec_flags ("events",
676
 						       P_("Events"),
677
 						       P_("The event mask that decides what kind of GdkEvents this widget gets"),
678
 						       GDK_TYPE_EVENT_MASK,
679
 						       GDK_STRUCTURE_MASK,
680
 						       GTK_PARAM_READWRITE));
681
  g_object_class_install_property (gobject_class,
682
				   PROP_EXTENSION_EVENTS,
683
				   g_param_spec_enum ("extension-events",
684
 						      P_("Extension events"),
685
 						      P_("The mask that decides what kind of extension events this widget gets"),
686
 						      GDK_TYPE_EXTENSION_MODE,
687
 						      GDK_EXTENSION_EVENTS_NONE,
688
 						      GTK_PARAM_READWRITE));
689
  g_object_class_install_property (gobject_class,
690
				   PROP_NO_SHOW_ALL,
691
				   g_param_spec_boolean ("no-show-all",
692
 							 P_("No show all"),
693
 							 P_("Whether gtk_widget_show_all() should not affect this widget"),
694
 							 FALSE,
695
 							 GTK_PARAM_READWRITE));
696
697
/**
698
 * GtkWidget:has-tooltip:
699
 *
700
 * Enables or disables the emission of #GtkWidget::query-tooltip on @widget.  
701
 * A value of %TRUE indicates that @widget can have a tooltip, in this case
702
 * the widget will be queried using #GtkWidget::query-tooltip to determine
703
 * whether it will provide a tooltip or not.
704
 *
705
 * Note that setting this property to %TRUE for the first time will change
706
 * the event masks of the GdkWindows of this widget to include leave-notify
707
 * and motion-notify events.  This cannot and will not be undone when the
708
 * property is set to %FALSE again.
709
 *
710
 * Since: 2.12
711
 */
712
  g_object_class_install_property (gobject_class,
713
				   PROP_HAS_TOOLTIP,
714
				   g_param_spec_boolean ("has-tooltip",
715
 							 P_("Has tooltip"),
716
 							 P_("Whether this widget has a tooltip"),
717
 							 FALSE,
718
 							 GTK_PARAM_READWRITE));
719
  /**
720
   * GtkWidget:tooltip-text:
721
   *
722
   * Sets the text of tooltip to be the given string.
723
   *
724
   * Also see gtk_tooltip_set_text().
725
   *
726
   * This is a convenience property which will take care of getting the
727
   * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
728
   * will automatically be set to %TRUE and there will be taken care of
729
   * #GtkWidget::query-tooltip in the default signal handler.
730
   *
731
   * Since: 2.12
732
   */
733
  g_object_class_install_property (gobject_class,
734
                                   PROP_TOOLTIP_TEXT,
735
                                   g_param_spec_string ("tooltip-text",
736
                                                        P_("Tooltip Text"),
737
                                                        P_("The contents of the tooltip for this widget"),
738
                                                        NULL,
739
                                                        GTK_PARAM_READWRITE));
740
  /**
741
   * GtkWidget:tooltip-markup:
742
   *
743
   * Sets the text of tooltip to be the given string, which is marked up
744
   * with the <link linkend="PangoMarkupFormat">Pango text markup language</link>.
745
   * Also see gtk_tooltip_set_markup().
746
   *
747
   * This is a convenience property which will take care of getting the
748
   * tooltip shown if the given string is not %NULL: #GtkWidget:has-tooltip
749
   * will automatically be set to %TRUE and there will be taken care of
750
   * #GtkWidget::query-tooltip in the default signal handler.
751
   *
752
   * Since: 2.12
753
   */
754
  g_object_class_install_property (gobject_class,
755
				   PROP_TOOLTIP_MARKUP,
756
				   g_param_spec_string ("tooltip-markup",
757
 							P_("Tooltip markup"),
758
							P_("The contents of the tooltip for this widget"),
759
							NULL,
760
							GTK_PARAM_READWRITE));
761
762
  /**
763
   * GtkWidget:window:
764
   *
765
   * The widget's window if it is realized, %NULL otherwise.
766
   *
767
   * Since: 2.14
768
   */
769
  g_object_class_install_property (gobject_class,
770
				   PROP_WINDOW,
771
				   g_param_spec_object ("window",
772
 							P_("Window"),
773
							P_("The widget's window if it is realized"),
774
							GDK_TYPE_WINDOW,
775
							GTK_PARAM_READABLE));
776
777
#ifdef MAEMO_CHANGES
778
  /**
779
   * GtkWidget:tap-and-hold-state:
780
   *
781
   * Sets the state (#GtkStateType) to be used to the tap and hold
782
   * functionality. The default is GTK_STATE_NORMAL.
783
   *
784
   * Deprecated: Functionality for setting and getting this propery is not
785
   * implemented.
786
   *
787
   * Since: maemo 1.0
788
   * Stability: Unstable
789
   */
790
  g_object_class_install_property (gobject_class,
791
                                   PROP_TAP_AND_HOLD,
792
                                   g_param_spec_int ("tap-and-hold-state",
793
                                                     P_("Tap and hold State type"),
794
                                                     P_("Sets the state to be used to the tap and hold functionality. The default is GTK_STATE_NORMAL"),
795
                                                     0,
796
                                                     4, /*4 == Last state in GTK+-2.0*/
797
                                                     GTK_STATE_NORMAL,
798
                                                     G_PARAM_READWRITE));
799
800
#endif /* MAEMO_CHANGES */
801
802
  widget_signals[SHOW] =
803
    g_signal_new (I_("show"),
804
		  G_TYPE_FROM_CLASS (gobject_class),
805
		  G_SIGNAL_RUN_FIRST,
806
		  G_STRUCT_OFFSET (GtkWidgetClass, show),
807
		  NULL, NULL,
808
		  _gtk_marshal_VOID__VOID,
809
		  G_TYPE_NONE, 0);
810
  widget_signals[HIDE] =
811
    g_signal_new (I_("hide"),
812
		  G_TYPE_FROM_CLASS (gobject_class),
813
		  G_SIGNAL_RUN_FIRST,
814
		  G_STRUCT_OFFSET (GtkWidgetClass, hide),
815
		  NULL, NULL,
816
		  _gtk_marshal_VOID__VOID,
817
		  G_TYPE_NONE, 0);
818
  widget_signals[MAP] =
819
    g_signal_new (I_("map"),
820
		  G_TYPE_FROM_CLASS (gobject_class),
821
		  G_SIGNAL_RUN_FIRST,
822
		  G_STRUCT_OFFSET (GtkWidgetClass, map),
823
		  NULL, NULL,
824
		  _gtk_marshal_VOID__VOID,
825
		  G_TYPE_NONE, 0);
826
  widget_signals[UNMAP] =
827
    g_signal_new (I_("unmap"),
828
		  G_TYPE_FROM_CLASS (gobject_class),
829
		  G_SIGNAL_RUN_FIRST,
830
		  G_STRUCT_OFFSET (GtkWidgetClass, unmap),
831
		  NULL, NULL,
832
		  _gtk_marshal_VOID__VOID,
833
		  G_TYPE_NONE, 0);
834
  widget_signals[REALIZE] =
835
    g_signal_new (I_("realize"),
836
		  G_TYPE_FROM_CLASS (gobject_class),
837
		  G_SIGNAL_RUN_FIRST,
838
		  G_STRUCT_OFFSET (GtkWidgetClass, realize),
839
		  NULL, NULL,
840
		  _gtk_marshal_VOID__VOID,
841
		  G_TYPE_NONE, 0);
842
  widget_signals[UNREALIZE] =
843
    g_signal_new (I_("unrealize"),
844
		  G_TYPE_FROM_CLASS (gobject_class),
845
		  G_SIGNAL_RUN_LAST,
846
		  G_STRUCT_OFFSET (GtkWidgetClass, unrealize),
847
		  NULL, NULL,
848
		  _gtk_marshal_VOID__VOID,
849
		  G_TYPE_NONE, 0);
850
  widget_signals[SIZE_REQUEST] =
851
    g_signal_new (I_("size-request"),
852
		  G_TYPE_FROM_CLASS (gobject_class),
853
		  G_SIGNAL_RUN_FIRST,
854
		  G_STRUCT_OFFSET (GtkWidgetClass, size_request),
855
		  NULL, NULL,
856
		  _gtk_marshal_VOID__BOXED,
857
		  G_TYPE_NONE, 1,
858
		  GTK_TYPE_REQUISITION | G_SIGNAL_TYPE_STATIC_SCOPE);
859
  widget_signals[SIZE_ALLOCATE] = 
860
    g_signal_new (I_("size-allocate"),
861
		  G_TYPE_FROM_CLASS (gobject_class),
862
		  G_SIGNAL_RUN_FIRST,
863
		  G_STRUCT_OFFSET (GtkWidgetClass, size_allocate),
864
		  NULL, NULL,
865
		  _gtk_marshal_VOID__BOXED,
866
		  G_TYPE_NONE, 1,
867
		  GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
868
869
  widget_signals[STATE_CHANGED] =
870
    g_signal_new (I_("state-changed"),
871
		  G_TYPE_FROM_CLASS (gobject_class),
872
		  G_SIGNAL_RUN_FIRST,
873
		  G_STRUCT_OFFSET (GtkWidgetClass, state_changed),
874
		  NULL, NULL,
875
		  _gtk_marshal_VOID__ENUM,
876
		  G_TYPE_NONE, 1,
877
		  GTK_TYPE_STATE_TYPE);
878
879
  /**
880
   * GtkWidget::parent-set:
881
   * @widget: the object on which the signal is emitted
882
   * @old_parent: the previous parent, or %NULL if the widget 
883
   *   just got its initial parent.
884
   *
885
   * The ::parent-set signal is emitted when a new parent 
886
   * has been set on a widget. 
887
   */
888
  widget_signals[PARENT_SET] =
889
    g_signal_new (I_("parent-set"),
890
		  G_TYPE_FROM_CLASS (gobject_class),
891
		  G_SIGNAL_RUN_FIRST,
892
		  G_STRUCT_OFFSET (GtkWidgetClass, parent_set),
893
		  NULL, NULL,
894
		  _gtk_marshal_VOID__OBJECT,
895
		  G_TYPE_NONE, 1,
896
		  GTK_TYPE_WIDGET);
897
898
  /**
899
   * GtkWidget::hierarchy-changed:
900
   * @widget: the object on which the signal is emitted
901
   * @previous_toplevel: the previous toplevel ancestor, or %NULL
902
   *   if the widget was previously unanchored
903
   *
904
   * The ::hierarchy-changed signal is emitted when the
905
   * anchored state of a widget changes. A widget is
906
   * <firstterm>anchored</firstterm> when its toplevel
907
   * ancestor is a #GtkWindow. This signal is emitted when
908
   * a widget changes from un-anchored to anchored or vice-versa.
909
   */
910
  widget_signals[HIERARCHY_CHANGED] =
911
    g_signal_new (I_("hierarchy-changed"),
912
		  G_TYPE_FROM_CLASS (gobject_class),
913
		  G_SIGNAL_RUN_LAST,
914
		  G_STRUCT_OFFSET (GtkWidgetClass, hierarchy_changed),
915
		  NULL, NULL,
916
		  _gtk_marshal_VOID__OBJECT,
917
		  G_TYPE_NONE, 1,
918
		  GTK_TYPE_WIDGET);
919
920
  /**
921
   * GtkWidget::style-set:
922
   * @widget: the object on which the signal is emitted
923
   * @previous_style: the previous style, or %NULL if the widget 
924
   *   just got its initial style 
925
   *
926
   * The ::style-set signal is emitted when a new style has been set 
927
   * on a widget. Note that style-modifying functions like 
928
   * gtk_widget_modify_base() also cause this signal to be emitted.
929
   */
930
  widget_signals[STYLE_SET] =
931
    g_signal_new (I_("style-set"),
932
		  G_TYPE_FROM_CLASS (gobject_class),
933
		  G_SIGNAL_RUN_FIRST,
934
		  G_STRUCT_OFFSET (GtkWidgetClass, style_set),
935
		  NULL, NULL,
936
		  _gtk_marshal_VOID__OBJECT,
937
		  G_TYPE_NONE, 1,
938
		  GTK_TYPE_STYLE);
939
/**
940
 * GtkWidget::direction-changed:
941
 * @widget: the object on which the signal is emitted
942
 * @previous_direction: the previous text direction of @widget
943
 *
944
 * The ::direction-changed signal is emitted when the text direction
945
 * of a widget changes.
946
 */
947
  widget_signals[DIRECTION_CHANGED] =
948
    g_signal_new (I_("direction-changed"),
949
		  G_TYPE_FROM_CLASS (gobject_class),
950
		  G_SIGNAL_RUN_FIRST,
951
		  G_STRUCT_OFFSET (GtkWidgetClass, direction_changed),
952
		  NULL, NULL,
953
		  _gtk_marshal_VOID__ENUM,
954
		  G_TYPE_NONE, 1,
955
		  GTK_TYPE_TEXT_DIRECTION);
956
957
  /**
958
   * GtkWidget::grab-notify:
959
   * @widget: the object which received the signal
960
   * @was_grabbed: %FALSE if the widget becomes shadowed, %TRUE
961
   *               if it becomes unshadowed
962
   *
963
   * The ::grab-notify signal is emitted when a widget becomes
964
   * shadowed by a GTK+ grab (not a pointer or keyboard grab) on 
965
   * another widget, or when it becomes unshadowed due to a grab 
966
   * being removed.
967
   * 
968
   * A widget is shadowed by a gtk_grab_add() when the topmost 
969
   * grab widget in the grab stack of its window group is not 
970
   * its ancestor.
971
   */
972
  widget_signals[GRAB_NOTIFY] =
973
    g_signal_new (I_("grab-notify"),
974
		  G_TYPE_FROM_CLASS (gobject_class),
975
		  G_SIGNAL_RUN_FIRST,
976
                  G_STRUCT_OFFSET (GtkWidgetClass, grab_notify),
977
		  NULL, NULL,
978
		  _gtk_marshal_VOID__BOOLEAN,
979
		  G_TYPE_NONE, 1,
980
		  G_TYPE_BOOLEAN);
981
982
/**
983
 * GtkWidget::child-notify:
984
 * @widget: the object which received the signal
985
 * @pspec: the #GParamSpec of the changed child property
986
 *
987
 * The ::child-notify signal is emitted for each 
988
 * <link linkend="child-properties">child property</link>  that has
989
 * changed on an object. The signal's detail holds the property name. 
990
 */
991
  widget_signals[CHILD_NOTIFY] =
992
    g_signal_new (I_("child-notify"),
993
		   G_TYPE_FROM_CLASS (gobject_class),
994
		   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
995
		   G_STRUCT_OFFSET (GtkWidgetClass, child_notify),
996
		   NULL, NULL,
997
		   g_cclosure_marshal_VOID__PARAM,
998
		   G_TYPE_NONE, 1,
999
		   G_TYPE_PARAM);
1000
  widget_signals[MNEMONIC_ACTIVATE] =
1001
    g_signal_new (I_("mnemonic-activate"),
1002
		  G_TYPE_FROM_CLASS (gobject_class),
1003
		  G_SIGNAL_RUN_LAST,
1004
		  G_STRUCT_OFFSET (GtkWidgetClass, mnemonic_activate),
1005
		  _gtk_boolean_handled_accumulator, NULL,
1006
		  _gtk_marshal_BOOLEAN__BOOLEAN,
1007
		  G_TYPE_BOOLEAN, 1,
1008
		  G_TYPE_BOOLEAN);
1009
  widget_signals[GRAB_FOCUS] =
1010
    g_signal_new (I_("grab-focus"),
1011
		  G_TYPE_FROM_CLASS (gobject_class),
1012
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1013
		  G_STRUCT_OFFSET (GtkWidgetClass, grab_focus),
1014
		  NULL, NULL,
1015
		  _gtk_marshal_VOID__VOID,
1016
		  G_TYPE_NONE, 0);
1017
  widget_signals[FOCUS] =
1018
    g_signal_new (I_("focus"),
1019
		  G_TYPE_FROM_CLASS (object_class),
1020
		  G_SIGNAL_RUN_LAST,
1021
		  G_STRUCT_OFFSET (GtkWidgetClass, focus),
1022
		  _gtk_boolean_handled_accumulator, NULL,
1023
		  _gtk_marshal_BOOLEAN__ENUM,
1024
		  G_TYPE_BOOLEAN, 1,
1025
		  GTK_TYPE_DIRECTION_TYPE);
1026
  widget_signals[MOVE_FOCUS] =
1027
    g_signal_new_class_handler (I_("move-focus"),
1028
                                G_TYPE_FROM_CLASS (object_class),
1029
                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1030
                                G_CALLBACK (gtk_widget_real_move_focus),
1031
                                NULL, NULL,
1032
                                _gtk_marshal_VOID__ENUM,
1033
                                G_TYPE_NONE,
1034
                                1,
1035
                                GTK_TYPE_DIRECTION_TYPE);
1036
  /**
1037
   * GtkWidget::event:
1038
   * @widget: the object which received the signal.
1039
   * @event: the #GdkEvent which triggered this signal
1040
   *
1041
   * The GTK+ main loop will emit three signals for each GDK event delivered
1042
   * to a widget: one generic ::event signal, another, more specific,
1043
   * signal that matches the type of event delivered (e.g. 
1044
   * #GtkWidget::key-press-event) and finally a generic 
1045
   * #GtkWidget::event-after signal.
1046
   *
1047
   * Returns: %TRUE to stop other handlers from being invoked for the event 
1048
   * and to cancel the emission of the second specific ::event signal.
1049
   *   %FALSE to propagate the event further and to allow the emission of 
1050
   *   the second signal. The ::event-after signal is emitted regardless of
1051
   *   the return value.
1052
   */
1053
  widget_signals[EVENT] =
1054
    g_signal_new (I_("event"),
1055
		  G_TYPE_FROM_CLASS (gobject_class),
1056
		  G_SIGNAL_RUN_LAST,
1057
		  G_STRUCT_OFFSET (GtkWidgetClass, event),
1058
		  _gtk_boolean_handled_accumulator, NULL,
1059
		  _gtk_marshal_BOOLEAN__BOXED,
1060
		  G_TYPE_BOOLEAN, 1,
1061
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1062
1063
  /**
1064
   * GtkWidget::event-after:
1065
   * @widget: the object which received the signal.
1066
   * @event: the #GdkEvent which triggered this signal
1067
   *
1068
   * After the emission of the #GtkWidget::event signal and (optionally) 
1069
   * the second more specific signal, ::event-after will be emitted 
1070
   * regardless of the previous two signals handlers return values.
1071
   *
1072
   */
1073
  widget_signals[EVENT_AFTER] =
1074
    g_signal_new (I_("event-after"),
1075
		  G_TYPE_FROM_CLASS (gobject_class),
1076
		  0,
1077
		  0,
1078
		  NULL, NULL,
1079
		  _gtk_marshal_VOID__BOXED,
1080
		  G_TYPE_NONE, 1,
1081
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1082
1083
  /**
1084
   * GtkWidget::button-press-event:
1085
   * @widget: the object which received the signal.
1086
   * @event: the #GdkEventButton which triggered this signal
1087
   *
1088
   * The ::button-press-event signal will be emitted when a button
1089
   * (typically from a mouse) is pressed.
1090
   *
1091
   * To receive this signal, the #GdkWindow associated to the 
1092
   * widget needs to enable the #GDK_BUTTON_PRESS_MASK mask.
1093
   *
1094
   * This signal will be sent to the grab widget if there is one.
1095
   *
1096
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1097
   *   %FALSE to propagate the event further.
1098
   */
1099
  widget_signals[BUTTON_PRESS_EVENT] =
1100
    g_signal_new (I_("button-press-event"),
1101
		  G_TYPE_FROM_CLASS (gobject_class),
1102
		  G_SIGNAL_RUN_LAST,
1103
		  G_STRUCT_OFFSET (GtkWidgetClass, button_press_event),
1104
		  _gtk_boolean_handled_accumulator, NULL,
1105
		  _gtk_marshal_BOOLEAN__BOXED,
1106
		  G_TYPE_BOOLEAN, 1,
1107
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1108
1109
  /**
1110
   * GtkWidget::button-release-event:
1111
   * @widget: the object which received the signal.
1112
   * @event: the #GdkEventButton which triggered this signal
1113
   *
1114
   * The ::button-release-event signal will be emitted when a button
1115
   * (typically from a mouse) is released.
1116
   *
1117
   * To receive this signal, the #GdkWindow associated to the 
1118
   * widget needs to enable the #GDK_BUTTON_RELEASE_MASK mask.
1119
   *
1120
   * This signal will be sent to the grab widget if there is one.
1121
   *
1122
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1123
   *   %FALSE to propagate the event further.
1124
   */
1125
  widget_signals[BUTTON_RELEASE_EVENT] =
1126
    g_signal_new (I_("button-release-event"),
1127
		  G_TYPE_FROM_CLASS (gobject_class),
1128
		  G_SIGNAL_RUN_LAST,
1129
		  G_STRUCT_OFFSET (GtkWidgetClass, button_release_event),
1130
		  _gtk_boolean_handled_accumulator, NULL,
1131
		  _gtk_marshal_BOOLEAN__BOXED,
1132
		  G_TYPE_BOOLEAN, 1,
1133
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1134
1135
  /**
1136
   * GtkWidget::scroll-event:
1137
   * @widget: the object which received the signal.
1138
   * @event: the #GdkEventScroll which triggered this signal
1139
   *
1140
   * The ::scroll-event signal is emitted when a button in the 4 to 7
1141
   * range is pressed. Wheel mice are usually configured to generate 
1142
   * button press events for buttons 4 and 5 when the wheel is turned.
1143
   *
1144
   * To receive this signal, the #GdkWindow associated to the widget needs
1145
   * to enable the #GDK_BUTTON_PRESS_MASK mask.
1146
   *
1147
   * This signal will be sent to the grab widget if there is one.
1148
   *
1149
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1150
   *   %FALSE to propagate the event further.
1151
   */
1152
  widget_signals[SCROLL_EVENT] =
1153
    g_signal_new (I_("scroll-event"),
1154
		  G_TYPE_FROM_CLASS (gobject_class),
1155
		  G_SIGNAL_RUN_LAST,
1156
		  G_STRUCT_OFFSET (GtkWidgetClass, scroll_event),
1157
		  _gtk_boolean_handled_accumulator, NULL,
1158
		  _gtk_marshal_BOOLEAN__BOXED,
1159
		  G_TYPE_BOOLEAN, 1,
1160
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1161
  /**
1162
   * GtkWidget::motion-notify-event:
1163
   * @widget: the object which received the signal.
1164
   * @event: the #GdkEventMotion which triggered this signal
1165
   *
1166
   * The ::motion-notify-event signal is emitted when the pointer moves 
1167
   * over the widget's #GdkWindow.
1168
   *
1169
   * To receive this signal, the #GdkWindow associated to the widget 
1170
   * needs to enable the #GDK_POINTER_MOTION_MASK mask.
1171
   *
1172
   * This signal will be sent to the grab widget if there is one.
1173
   *
1174
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1175
   *   %FALSE to propagate the event further.
1176
   */
1177
  widget_signals[MOTION_NOTIFY_EVENT] =
1178
    g_signal_new (I_("motion-notify-event"),
1179
		  G_TYPE_FROM_CLASS (gobject_class),
1180
		  G_SIGNAL_RUN_LAST,
1181
		  G_STRUCT_OFFSET (GtkWidgetClass, motion_notify_event),
1182
		  _gtk_boolean_handled_accumulator, NULL,
1183
		  _gtk_marshal_BOOLEAN__BOXED,
1184
		  G_TYPE_BOOLEAN, 1,
1185
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1186
1187
  /**
1188
   * GtkWidget::composited-changed:
1189
   * @widget: the object on which the signal is emitted
1190
   *
1191
   * The ::composited-changed signal is emitted when the composited
1192
   * status of @widget<!-- -->s screen changes. 
1193
   * See gdk_screen_is_composited().
1194
   */
1195
  widget_signals[COMPOSITED_CHANGED] =
1196
    g_signal_new (I_("composited-changed"),
1197
		  G_TYPE_FROM_CLASS (gobject_class),
1198
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1199
		  G_STRUCT_OFFSET (GtkWidgetClass, composited_changed),
1200
		  NULL, NULL,
1201
		  _gtk_marshal_VOID__VOID,
1202
		  G_TYPE_NONE, 0);
1203
1204
  /**
1205
   * GtkWidget::keynav-failed:
1206
   * @widget: the object which received the signal
1207
   * @direction: the direction of movement
1208
   *
1209
   * Gets emitted if keyboard navigation fails. 
1210
   * See gtk_widget_keynav_failed() for details.
1211
   *
1212
   * Returns: %TRUE if stopping keyboard navigation is fine, %FALSE
1213
   *          if the emitting widget should try to handle the keyboard
1214
   *          navigation attempt in its parent container(s).
1215
   *
1216
   * Since: 2.12
1217
   **/
1218
  widget_signals[KEYNAV_FAILED] =
1219
    g_signal_new_class_handler (I_("keynav-failed"),
1220
                                G_TYPE_FROM_CLASS (gobject_class),
1221
                                G_SIGNAL_RUN_LAST,
1222
                                G_CALLBACK (gtk_widget_real_keynav_failed),
1223
                                _gtk_boolean_handled_accumulator, NULL,
1224
                                _gtk_marshal_BOOLEAN__ENUM,
1225
                                G_TYPE_BOOLEAN, 1,
1226
                                GTK_TYPE_DIRECTION_TYPE);
1227
1228
  /**
1229
   * GtkWidget::delete-event:
1230
   * @widget: the object which received the signal
1231
   * @event: the event which triggered this signal
1232
   *
1233
   * The ::delete-event signal is emitted if a user requests that
1234
   * a toplevel window is closed. The default handler for this signal
1235
   * destroys the window. Connecting gtk_widget_hide_on_delete() to
1236
   * this signal will cause the window to be hidden instead, so that
1237
   * it can later be shown again without reconstructing it.
1238
   *
1239
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1240
   *   %FALSE to propagate the event further.
1241
   */
1242
  widget_signals[DELETE_EVENT] =
1243
    g_signal_new (I_("delete-event"),
1244
		  G_TYPE_FROM_CLASS (gobject_class),
1245
		  G_SIGNAL_RUN_LAST,
1246
		  G_STRUCT_OFFSET (GtkWidgetClass, delete_event),
1247
		  _gtk_boolean_handled_accumulator, NULL,
1248
		  _gtk_marshal_BOOLEAN__BOXED,
1249
		  G_TYPE_BOOLEAN, 1,
1250
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1251
1252
  /**
1253
   * GtkWidget::destroy-event:
1254
   * @widget: the object which received the signal.
1255
   * @event: the event which triggered this signal
1256
   *
1257
   * The ::destroy-event signal is emitted when a #GdkWindow is destroyed.
1258
   * You rarely get this signal, because most widgets disconnect themselves 
1259
   * from their window before they destroy it, so no widget owns the 
1260
   * window at destroy time.
1261
   * 
1262
   * To receive this signal, the #GdkWindow associated to the widget needs
1263
   * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
1264
   * automatically for all new windows.
1265
   *
1266
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1267
   *   %FALSE to propagate the event further.
1268
   */
1269
  widget_signals[DESTROY_EVENT] =
1270
    g_signal_new (I_("destroy-event"),
1271
		  G_TYPE_FROM_CLASS (gobject_class),
1272
		  G_SIGNAL_RUN_LAST,
1273
		  G_STRUCT_OFFSET (GtkWidgetClass, destroy_event),
1274
		  _gtk_boolean_handled_accumulator, NULL,
1275
		  _gtk_marshal_BOOLEAN__BOXED,
1276
		  G_TYPE_BOOLEAN, 1,
1277
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1278
1279
  /**
1280
   * GtkWidget::expose-event:
1281
   * @widget: the object which received the signal.
1282
   * @event: the #GdkEventExpose which triggered this signal
1283
   *
1284
   * The ::expose-event signal is emitted when an area of a previously
1285
   * obscured #GdkWindow is made visible and needs to be redrawn.
1286
   * #GTK_NO_WINDOW widgets will get a synthesized event from their parent 
1287
   * widget.
1288
   *
1289
   * To receive this signal, the #GdkWindow associated to the widget needs
1290
   * to enable the #GDK_EXPOSURE_MASK mask.
1291
   * 
1292
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1293
   *   %FALSE to propagate the event further.
1294
   */
1295
  widget_signals[EXPOSE_EVENT] =
1296
    g_signal_new (I_("expose-event"),
1297
		  G_TYPE_FROM_CLASS (gobject_class),
1298
		  G_SIGNAL_RUN_LAST,
1299
		  G_STRUCT_OFFSET (GtkWidgetClass, expose_event),
1300
		  _gtk_boolean_handled_accumulator, NULL,
1301
		  _gtk_marshal_BOOLEAN__BOXED,
1302
		  G_TYPE_BOOLEAN, 1,
1303
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1304
1305
  /**
1306
   * GtkWidget::key-press-event:
1307
   * @widget: the object which received the signal
1308
   * @event: the #GdkEventKey which triggered this signal
1309
   *
1310
   * The ::key-press-event signal is emitted when a key is pressed.
1311
   *
1312
   * To receive this signal, the #GdkWindow associated to the widget needs
1313
   * to enable the #GDK_KEY_PRESS_MASK mask.
1314
   *
1315
   * This signal will be sent to the grab widget if there is one.
1316
   *
1317
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1318
   *   %FALSE to propagate the event further.
1319
   */
1320
  widget_signals[KEY_PRESS_EVENT] =
1321
    g_signal_new (I_("key-press-event"),
1322
		  G_TYPE_FROM_CLASS (gobject_class),
1323
		  G_SIGNAL_RUN_LAST,
1324
		  G_STRUCT_OFFSET (GtkWidgetClass, key_press_event),
1325
		  _gtk_boolean_handled_accumulator, NULL,
1326
		  _gtk_marshal_BOOLEAN__BOXED,
1327
		  G_TYPE_BOOLEAN, 1,
1328
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1329
1330
  /**
1331
   * GtkWidget::key-release-event:
1332
   * @widget: the object which received the signal
1333
   * @event: the #GdkEventKey which triggered this signal
1334
   *
1335
   * The ::key-release-event signal is emitted when a key is pressed.
1336
   *
1337
   * To receive this signal, the #GdkWindow associated to the widget needs
1338
   * to enable the #GDK_KEY_RELEASE_MASK mask.
1339
   *
1340
   * This signal will be sent to the grab widget if there is one.
1341
   *
1342
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1343
   *   %FALSE to propagate the event further.
1344
   */
1345
  widget_signals[KEY_RELEASE_EVENT] =
1346
    g_signal_new (I_("key-release-event"),
1347
		  G_TYPE_FROM_CLASS (gobject_class),
1348
		  G_SIGNAL_RUN_LAST,
1349
		  G_STRUCT_OFFSET (GtkWidgetClass, key_release_event),
1350
		  _gtk_boolean_handled_accumulator, NULL,
1351
		  _gtk_marshal_BOOLEAN__BOXED,
1352
		  G_TYPE_BOOLEAN, 1,
1353
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1354
1355
  /**
1356
   * GtkWidget::enter-notify-event:
1357
   * @widget: the object which received the signal
1358
   * @event: the #GdkEventCrossing which triggered this signal
1359
   *
1360
   * The ::enter-notify-event will be emitted when the pointer enters
1361
   * the @widget's window.
1362
   *
1363
   * To receive this signal, the #GdkWindow associated to the widget needs
1364
   * to enable the #GDK_ENTER_NOTIFY_MASK mask.
1365
   *
1366
   * This signal will be sent to the grab widget if there is one.
1367
   *
1368
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1369
   *   %FALSE to propagate the event further.
1370
   */
1371
  widget_signals[ENTER_NOTIFY_EVENT] =
1372
    g_signal_new (I_("enter-notify-event"),
1373
		  G_TYPE_FROM_CLASS (gobject_class),
1374
		  G_SIGNAL_RUN_LAST,
1375
		  G_STRUCT_OFFSET (GtkWidgetClass, enter_notify_event),
1376
		  _gtk_boolean_handled_accumulator, NULL,
1377
		  _gtk_marshal_BOOLEAN__BOXED,
1378
		  G_TYPE_BOOLEAN, 1,
1379
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1380
1381
  /**
1382
   * GtkWidget::leave-notify-event:
1383
   * @widget: the object which received the signal
1384
   * @event: the #GdkEventCrossing which triggered this signal
1385
   *
1386
   * The ::leave-notify-event will be emitted when the pointer leaves
1387
   * the @widget's window.
1388
   *
1389
   * To receive this signal, the #GdkWindow associated to the widget needs
1390
   * to enable the #GDK_LEAVE_NOTIFY_MASK mask.
1391
   *
1392
   * This signal will be sent to the grab widget if there is one.
1393
   *
1394
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1395
   *   %FALSE to propagate the event further.
1396
   */
1397
  widget_signals[LEAVE_NOTIFY_EVENT] =
1398
    g_signal_new (I_("leave-notify-event"),
1399
		  G_TYPE_FROM_CLASS (gobject_class),
1400
		  G_SIGNAL_RUN_LAST,
1401
		  G_STRUCT_OFFSET (GtkWidgetClass, leave_notify_event),
1402
		  _gtk_boolean_handled_accumulator, NULL,
1403
		  _gtk_marshal_BOOLEAN__BOXED,
1404
		  G_TYPE_BOOLEAN, 1,
1405
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1406
1407
  /**
1408
   * GtkWidget::configure-event
1409
   * @widget: the object which received the signal
1410
   * @event: the #GdkEventConfigure which triggered this signal
1411
   *
1412
   * The ::configure-event signal will be emitted when the size, position or
1413
   * stacking of the @widget's window has changed.
1414
   *
1415
   * To receive this signal, the #GdkWindow associated to the widget needs
1416
   * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
1417
   * automatically for all new windows.
1418
   *
1419
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1420
   *   %FALSE to propagate the event further.
1421
   */
1422
  widget_signals[CONFIGURE_EVENT] =
1423
    g_signal_new (I_("configure-event"),
1424
		  G_TYPE_FROM_CLASS (gobject_class),
1425
		  G_SIGNAL_RUN_LAST,
1426
		  G_STRUCT_OFFSET (GtkWidgetClass, configure_event),
1427
		  _gtk_boolean_handled_accumulator, NULL,
1428
		  _gtk_marshal_BOOLEAN__BOXED,
1429
		  G_TYPE_BOOLEAN, 1,
1430
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1431
1432
  /**
1433
   * GtkWidget::focus-in-event
1434
   * @widget: the object which received the signal
1435
   * @event: the #GdkEventFocus which triggered this signal
1436
   *
1437
   * The ::focus-in-event signal will be emitted when the keyboard focus
1438
   * enters the @widget's window.
1439
   *
1440
   * To receive this signal, the #GdkWindow associated to the widget needs
1441
   * to enable the #GDK_FOCUS_CHANGE_MASK mask.
1442
   *
1443
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1444
   *   %FALSE to propagate the event further.
1445
   */
1446
  widget_signals[FOCUS_IN_EVENT] =
1447
    g_signal_new (I_("focus-in-event"),
1448
		  G_TYPE_FROM_CLASS (gobject_class),
1449
		  G_SIGNAL_RUN_LAST,
1450
		  G_STRUCT_OFFSET (GtkWidgetClass, focus_in_event),
1451
		  _gtk_boolean_handled_accumulator, NULL,
1452
		  _gtk_marshal_BOOLEAN__BOXED,
1453
		  G_TYPE_BOOLEAN, 1,
1454
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1455
1456
  /**
1457
   * GtkWidget::focus-out-event
1458
   * @widget: the object which received the signal
1459
   * @event: the #GdkEventFocus which triggered this signal
1460
   *
1461
   * The ::focus-out-event signal will be emitted when the keyboard focus
1462
   * leaves the @widget's window.
1463
   *
1464
   * To receive this signal, the #GdkWindow associated to the widget needs
1465
   * to enable the #GDK_FOCUS_CHANGE_MASK mask.
1466
   *
1467
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1468
   *   %FALSE to propagate the event further.
1469
   */
1470
  widget_signals[FOCUS_OUT_EVENT] =
1471
    g_signal_new (I_("focus-out-event"),
1472
		  G_TYPE_FROM_CLASS (gobject_class),
1473
		  G_SIGNAL_RUN_LAST,
1474
		  G_STRUCT_OFFSET (GtkWidgetClass, focus_out_event),
1475
		  _gtk_boolean_handled_accumulator, NULL,
1476
		  _gtk_marshal_BOOLEAN__BOXED,
1477
		  G_TYPE_BOOLEAN, 1,
1478
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1479
1480
  /**
1481
   * GtkWidget::map-event
1482
   * @widget: the object which received the signal
1483
   * @event: the #GdkEventAny which triggered this signal
1484
   *
1485
   * The ::map-event signal will be emitted when the @widget's window is
1486
   * mapped. A window is mapped when it becomes visible on the screen.
1487
   *
1488
   * To receive this signal, the #GdkWindow associated to the widget needs
1489
   * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
1490
   * automatically for all new windows.
1491
   *
1492
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1493
   *   %FALSE to propagate the event further.
1494
   */
1495
  widget_signals[MAP_EVENT] =
1496
    g_signal_new (I_("map-event"),
1497
		  G_TYPE_FROM_CLASS (gobject_class),
1498
		  G_SIGNAL_RUN_LAST,
1499
		  G_STRUCT_OFFSET (GtkWidgetClass, map_event),
1500
		  _gtk_boolean_handled_accumulator, NULL,
1501
		  _gtk_marshal_BOOLEAN__BOXED,
1502
		  G_TYPE_BOOLEAN, 1,
1503
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1504
1505
  /**
1506
   * GtkWidget::unmap-event
1507
   * @widget: the object which received the signal
1508
   * @event: the #GdkEventAny which triggered this signal
1509
   *
1510
   * The ::unmap-event signal will be emitted when the @widget's window is
1511
   * unmapped. A window is unmapped when it becomes invisible on the screen.
1512
   *
1513
   * To receive this signal, the #GdkWindow associated to the widget needs
1514
   * to enable the #GDK_STRUCTURE_MASK mask. GDK will enable this mask
1515
   * automatically for all new windows.
1516
   *
1517
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1518
   *   %FALSE to propagate the event further.
1519
   */
1520
  widget_signals[UNMAP_EVENT] =
1521
    g_signal_new (I_("unmap-event"),
1522
		  G_TYPE_FROM_CLASS (gobject_class),
1523
		  G_SIGNAL_RUN_LAST,
1524
		  G_STRUCT_OFFSET (GtkWidgetClass, unmap_event),
1525
		  _gtk_boolean_handled_accumulator, NULL,
1526
		  _gtk_marshal_BOOLEAN__BOXED,
1527
		  G_TYPE_BOOLEAN, 1,
1528
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1529
1530
  /**
1531
   * GtkWidget::property-notify-event
1532
   * @widget: the object which received the signal
1533
   * @event: the #GdkEventProperty which triggered this signal
1534
   *
1535
   * The ::property-notify-event signal will be emitted when a property on
1536
   * the @widget's window has been changed or deleted.
1537
   *
1538
   * To receive this signal, the #GdkWindow associated to the widget needs
1539
   * to enable the #GDK_PROPERTY_CHANGE_MASK mask.
1540
   *
1541
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1542
   *   %FALSE to propagate the event further.
1543
   */
1544
  widget_signals[PROPERTY_NOTIFY_EVENT] =
1545
    g_signal_new (I_("property-notify-event"),
1546
		  G_TYPE_FROM_CLASS (gobject_class),
1547
		  G_SIGNAL_RUN_LAST,
1548
		  G_STRUCT_OFFSET (GtkWidgetClass, property_notify_event),
1549
		  _gtk_boolean_handled_accumulator, NULL,
1550
		  _gtk_marshal_BOOLEAN__BOXED,
1551
		  G_TYPE_BOOLEAN, 1,
1552
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1553
1554
  /**
1555
   * GtkWidget::selection-clear-event
1556
   * @widget: the object which received the signal
1557
   * @event: the #GdkEventSelection which triggered this signal
1558
   *
1559
   * The ::selection-clear-event signal will be emitted when the
1560
   * the @widget's window has lost ownership of a selection.
1561
   *
1562
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1563
   *   %FALSE to propagate the event further.
1564
   */
1565
  widget_signals[SELECTION_CLEAR_EVENT] =
1566
    g_signal_new (I_("selection-clear-event"),
1567
		  G_TYPE_FROM_CLASS (gobject_class),
1568
		  G_SIGNAL_RUN_LAST,
1569
		  G_STRUCT_OFFSET (GtkWidgetClass, selection_clear_event),
1570
		  _gtk_boolean_handled_accumulator, NULL,
1571
		  _gtk_marshal_BOOLEAN__BOXED,
1572
		  G_TYPE_BOOLEAN, 1,
1573
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1574
1575
  /**
1576
   * GtkWidget::selection-request-event
1577
   * @widget: the object which received the signal
1578
   * @event: the #GdkEventSelection which triggered this signal
1579
   *
1580
   * The ::selection-request-event signal will be emitted when
1581
   * another client requests ownership of the selection owned by
1582
   * the @widget's window.
1583
   *
1584
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1585
   *   %FALSE to propagate the event further.
1586
   */
1587
  widget_signals[SELECTION_REQUEST_EVENT] =
1588
    g_signal_new (I_("selection-request-event"),
1589
		  G_TYPE_FROM_CLASS (gobject_class),
1590
		  G_SIGNAL_RUN_LAST,
1591
		  G_STRUCT_OFFSET (GtkWidgetClass, selection_request_event),
1592
		  _gtk_boolean_handled_accumulator, NULL,
1593
		  _gtk_marshal_BOOLEAN__BOXED,
1594
		  G_TYPE_BOOLEAN, 1,
1595
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1596
1597
  widget_signals[SELECTION_NOTIFY_EVENT] =
1598
    g_signal_new (I_("selection-notify-event"),
1599
		  G_TYPE_FROM_CLASS (gobject_class),
1600
		  G_SIGNAL_RUN_LAST,
1601
		  G_STRUCT_OFFSET (GtkWidgetClass, selection_notify_event),
1602
		  _gtk_boolean_handled_accumulator, NULL,
1603
		  _gtk_marshal_BOOLEAN__BOXED,
1604
		  G_TYPE_BOOLEAN, 1,
1605
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1606
1607
  widget_signals[SELECTION_RECEIVED] =
1608
    g_signal_new (I_("selection-received"),
1609
		  G_TYPE_FROM_CLASS (gobject_class),
1610
		  G_SIGNAL_RUN_LAST,
1611
		  G_STRUCT_OFFSET (GtkWidgetClass, selection_received),
1612
		  NULL, NULL,
1613
		  _gtk_marshal_VOID__BOXED_UINT,
1614
		  G_TYPE_NONE, 2,
1615
		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
1616
		  G_TYPE_UINT);
1617
1618
  widget_signals[SELECTION_GET] =
1619
    g_signal_new (I_("selection-get"),
1620
		  G_TYPE_FROM_CLASS (gobject_class),
1621
		  G_SIGNAL_RUN_LAST,
1622
		  G_STRUCT_OFFSET (GtkWidgetClass, selection_get),
1623
		  NULL, NULL,
1624
		  _gtk_marshal_VOID__BOXED_UINT_UINT,
1625
		  G_TYPE_NONE, 3,
1626
		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
1627
		  G_TYPE_UINT,
1628
		  G_TYPE_UINT);
1629
1630
  /**
1631
   * GtkWidget::proximity-in-event
1632
   * @widget: the object which received the signal
1633
   * @event: the #GdkEventProximity which triggered this signal
1634
   *
1635
   * To receive this signal the #GdkWindow associated to the widget needs
1636
   * to enable the #GDK_PROXIMITY_IN_MASK mask.
1637
   *
1638
   * This signal will be sent to the grab widget if there is one.
1639
   *
1640
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1641
   *   %FALSE to propagate the event further.
1642
   */
1643
  widget_signals[PROXIMITY_IN_EVENT] =
1644
    g_signal_new (I_("proximity-in-event"),
1645
		  G_TYPE_FROM_CLASS (gobject_class),
1646
		  G_SIGNAL_RUN_LAST,
1647
		  G_STRUCT_OFFSET (GtkWidgetClass, proximity_in_event),
1648
		  _gtk_boolean_handled_accumulator, NULL,
1649
		  _gtk_marshal_BOOLEAN__BOXED,
1650
		  G_TYPE_BOOLEAN, 1,
1651
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1652
1653
  /**
1654
   * GtkWidget::proximity-out-event
1655
   * @widget: the object which received the signal
1656
   * @event: the #GdkEventProximity which triggered this signal
1657
   *
1658
   * To receive this signal the #GdkWindow associated to the widget needs
1659
   * to enable the #GDK_PROXIMITY_OUT_MASK mask.
1660
   *
1661
   * This signal will be sent to the grab widget if there is one.
1662
   *
1663
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
1664
   *   %FALSE to propagate the event further.
1665
   */
1666
  widget_signals[PROXIMITY_OUT_EVENT] =
1667
    g_signal_new (I_("proximity-out-event"),
1668
		  G_TYPE_FROM_CLASS (gobject_class),
1669
		  G_SIGNAL_RUN_LAST,
1670
		  G_STRUCT_OFFSET (GtkWidgetClass, proximity_out_event),
1671
		  _gtk_boolean_handled_accumulator, NULL,
1672
		  _gtk_marshal_BOOLEAN__BOXED,
1673
		  G_TYPE_BOOLEAN, 1,
1674
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
1675
1676
  /**
1677
   * GtkWidget::drag-leave:
1678
   * @widget: the object which received the signal.
1679
   * @drag_context: the drag context
1680
   * @time: the timestamp of the motion event
1681
   *
1682
   * The ::drag-leave signal is emitted on the drop site when the cursor 
1683
   * leaves the widget. A typical reason to connect to this signal is to 
1684
   * undo things done in #GtkWidget::drag-motion, e.g. undo highlighting 
1685
   * with gtk_drag_unhighlight()
1686
   */
1687
  widget_signals[DRAG_LEAVE] =
1688
    g_signal_new (I_("drag-leave"),
1689
		  G_TYPE_FROM_CLASS (gobject_class),
1690
		  G_SIGNAL_RUN_LAST,
1691
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_leave),
1692
		  NULL, NULL,
1693
		  _gtk_marshal_VOID__OBJECT_UINT,
1694
		  G_TYPE_NONE, 2,
1695
		  GDK_TYPE_DRAG_CONTEXT,
1696
		  G_TYPE_UINT);
1697
1698
  /**
1699
   * GtkWidget::drag-begin:
1700
   * @widget: the object which received the signal
1701
   * @drag_context: the drag context
1702
   *
1703
   * The ::drag-begin signal is emitted on the drag source when a drag is 
1704
   * started. A typical reason to connect to this signal is to set up a 
1705
   * custom drag icon with gtk_drag_source_set_icon().
1706
   */
1707
  widget_signals[DRAG_BEGIN] =
1708
    g_signal_new (I_("drag-begin"),
1709
		  G_TYPE_FROM_CLASS (gobject_class),
1710
		  G_SIGNAL_RUN_LAST,
1711
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_begin),
1712
		  NULL, NULL,
1713
		  _gtk_marshal_VOID__OBJECT,
1714
		  G_TYPE_NONE, 1,
1715
		  GDK_TYPE_DRAG_CONTEXT);
1716
1717
  /**
1718
   * GtkWidget::drag-end:
1719
   * @widget: the object which received the signal
1720
   * @drag_context: the drag context
1721
   *
1722
   * The ::drag-end signal is emitted on the drag source when a drag is 
1723
   * finished.  A typical reason to connect to this signal is to undo 
1724
   * things done in #GtkWidget::drag-begin.
1725
   */
1726
  widget_signals[DRAG_END] =
1727
    g_signal_new (I_("drag-end"),
1728
		  G_TYPE_FROM_CLASS (gobject_class),
1729
		  G_SIGNAL_RUN_LAST,
1730
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_end),
1731
		  NULL, NULL,
1732
		  _gtk_marshal_VOID__OBJECT,
1733
		  G_TYPE_NONE, 1,
1734
		  GDK_TYPE_DRAG_CONTEXT);
1735
1736
  /**
1737
   * GtkWidget::drag-data-delete:
1738
   * @widget: the object which received the signal
1739
   * @drag_context: the drag context
1740
   *
1741
   * The ::drag-data-delete signal is emitted on the drag source when a drag 
1742
   * with the action %GDK_ACTION_MOVE is successfully completed. The signal 
1743
   * handler is responsible for deleting the data that has been dropped. What 
1744
   * "delete" means depends on the context of the drag operation. 
1745
   */
1746
  widget_signals[DRAG_DATA_DELETE] =
1747
    g_signal_new (I_("drag-data-delete"),
1748
		  G_TYPE_FROM_CLASS (gobject_class),
1749
		  G_SIGNAL_RUN_LAST,
1750
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_delete),
1751
		  NULL, NULL,
1752
		  _gtk_marshal_VOID__OBJECT,
1753
		  G_TYPE_NONE, 1,
1754
		  GDK_TYPE_DRAG_CONTEXT);
1755
1756
  /**
1757
   * GtkWidget::drag-failed:
1758
   * @widget: the object which received the signal
1759
   * @drag_context: the drag context
1760
   * @result: the result of the drag operation
1761
   *
1762
   * The ::drag-failed signal is emitted on the drag source when a drag has
1763
   * failed. The signal handler may hook custom code to handle a failed DND
1764
   * operation based on the type of error, it returns %TRUE is the failure has
1765
   * been already handled (not showing the default "drag operation failed"
1766
   * animation), otherwise it returns %FALSE.
1767
   *
1768
   * Return value: %TRUE if the failed drag operation has been already handled.
1769
   *
1770
   * Since: 2.12
1771
   */
1772
  widget_signals[DRAG_FAILED] =
1773
    g_signal_new (I_("drag-failed"),
1774
		  G_TYPE_FROM_CLASS (gobject_class),
1775
		  G_SIGNAL_RUN_LAST,
1776
		  0, _gtk_boolean_handled_accumulator, NULL,
1777
		  _gtk_marshal_BOOLEAN__OBJECT_ENUM,
1778
		  G_TYPE_BOOLEAN, 2,
1779
		  GDK_TYPE_DRAG_CONTEXT,
1780
		  GTK_TYPE_DRAG_RESULT);
1781
1782
  /**
1783
   * GtkWidget::drag-motion:
1784
   * @widget: the object which received the signal
1785
   * @drag_context: the drag context
1786
   * @x: the x coordinate of the current cursor position
1787
   * @y: the y coordinate of the current cursor position
1788
   * @time: the timestamp of the motion event
1789
   * @returns: whether the cursor position is in a drop zone
1790
   *
1791
   * The drag-motion signal is emitted on the drop site when the user
1792
   * moves the cursor over the widget during a drag. The signal handler
1793
   * must determine whether the cursor position is in a drop zone or not.
1794
   * If it is not in a drop zone, it returns %FALSE and no further processing
1795
   * is necessary. Otherwise, the handler returns %TRUE. In this case, the
1796
   * handler is responsible for providing the necessary information for
1797
   * displaying feedback to the user, by calling gdk_drag_status().
1798
   *
1799
   * If the decision whether the drop will be accepted or rejected can't be
1800
   * made based solely on the cursor position and the type of the data, the
1801
   * handler may inspect the dragged data by calling gtk_drag_get_data() and
1802
   * defer the gdk_drag_status() call to the #GtkWidget::drag-data-received
1803
   * handler. Note that you cannot not pass #GTK_DEST_DEFAULT_DROP,
1804
   * #GTK_DEST_DEFAULT_MOTION or #GTK_DEST_DEFAULT_ALL to gtk_drag_dest_set()
1805
   * when using the drag-motion signal that way.
1806
   *
1807
   * Also note that there is no drag-enter signal. The drag receiver has to
1808
   * keep track of whether he has received any drag-motion signals since the
1809
   * last #GtkWidget::drag-leave and if not, treat the drag-motion signal as
1810
   * an "enter" signal. Upon an "enter", the handler will typically highlight
1811
   * the drop site with gtk_drag_highlight().
1812
   * |[
1813
   * static void
1814
   * drag_motion (GtkWidget *widget,
1815
   *              GdkDragContext *context,
1816
   *              gint x,
1817
   *              gint y,
1818
   *              guint time)
1819
   * {
1820
   *   GdkAtom target;
1821
   *  
1822
   *   PrivateData *private_data = GET_PRIVATE_DATA (widget);
1823
   *  
1824
   *   if (!private_data->drag_highlight) 
1825
   *    {
1826
   *      private_data->drag_highlight = 1;
1827
   *      gtk_drag_highlight (widget);
1828
   *    }
1829
   *  
1830
   *   target = gtk_drag_dest_find_target (widget, context, NULL);
1831
   *   if (target == GDK_NONE)
1832
   *     gdk_drag_status (context, 0, time);
1833
   *   else 
1834
   *    {
1835
   *      private_data->pending_status = context->suggested_action;
1836
   *      gtk_drag_get_data (widget, context, target, time);
1837
   *    }
1838
   *  
1839
   *   return TRUE;
1840
   * }
1841
   *   
1842
   * static void
1843
   * drag_data_received (GtkWidget        *widget,
1844
   *                     GdkDragContext   *context,
1845
   *                     gint              x,
1846
   *                     gint              y,
1847
   *                     GtkSelectionData *selection_data,
1848
   *                     guint             info,
1849
   *                     guint             time)
1850
   * {
1851
   *   PrivateData *private_data = GET_PRIVATE_DATA (widget);
1852
   *   
1853
   *   if (private_data->suggested_action) 
1854
   *    {
1855
   *      private_data->suggested_action = 0;
1856
   *      
1857
   *     /&ast; We are getting this data due to a request in drag_motion,
1858
   *      * rather than due to a request in drag_drop, so we are just
1859
   *      * supposed to call gdk_drag_status (), not actually paste in 
1860
   *      * the data.
1861
   *      &ast;/
1862
   *      str = gtk_selection_data_get_text (selection_data);
1863
   *      if (!data_is_acceptable (str)) 
1864
   *        gdk_drag_status (context, 0, time);
1865
   *      else
1866
   *        gdk_drag_status (context, private_data->suggested_action, time);
1867
   *    }
1868
   *   else
1869
   *    {
1870
   *      /&ast; accept the drop &ast;/
1871
   *    }
1872
   * }
1873
   * ]|
1874
   */
1875
  widget_signals[DRAG_MOTION] =
1876
    g_signal_new (I_("drag-motion"),
1877
		  G_TYPE_FROM_CLASS (gobject_class),
1878
		  G_SIGNAL_RUN_LAST,
1879
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_motion),
1880
		  _gtk_boolean_handled_accumulator, NULL,
1881
		  _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
1882
		  G_TYPE_BOOLEAN, 4,
1883
		  GDK_TYPE_DRAG_CONTEXT,
1884
		  G_TYPE_INT,
1885
		  G_TYPE_INT,
1886
		  G_TYPE_UINT);
1887
1888
  /**
1889
   * GtkWidget::drag-drop:
1890
   * @widget: the object which received the signal
1891
   * @drag_context: the drag context
1892
   * @x: the x coordinate of the current cursor position
1893
   * @y: the y coordinate of the current cursor position
1894
   * @time: the timestamp of the motion event
1895
   * @returns: whether the cursor position is in a drop zone
1896
   *
1897
   * The ::drag-drop signal is emitted on the drop site when the user drops 
1898
   * the data onto the widget. The signal handler must determine whether 
1899
   * the cursor position is in a drop zone or not. If it is not in a drop 
1900
   * zone, it returns %FALSE and no further processing is necessary. 
1901
   * Otherwise, the handler returns %TRUE. In this case, the handler must 
1902
   * ensure that gtk_drag_finish() is called to let the source know that 
1903
   * the drop is done. The call to gtk_drag_finish() can be done either 
1904
   * directly or in a #GtkWidget::drag-data-received handler which gets 
1905
   * triggered by calling gtk_drag_get_data() to receive the data for one 
1906
   * or more of the supported targets.
1907
   */
1908
  widget_signals[DRAG_DROP] =
1909
    g_signal_new (I_("drag-drop"),
1910
		  G_TYPE_FROM_CLASS (gobject_class),
1911
		  G_SIGNAL_RUN_LAST,
1912
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_drop),
1913
		  _gtk_boolean_handled_accumulator, NULL,
1914
		  _gtk_marshal_BOOLEAN__OBJECT_INT_INT_UINT,
1915
		  G_TYPE_BOOLEAN, 4,
1916
		  GDK_TYPE_DRAG_CONTEXT,
1917
		  G_TYPE_INT,
1918
		  G_TYPE_INT,
1919
		  G_TYPE_UINT);
1920
1921
  /** 
1922
   * GtkWidget::drag-data-get:
1923
   * @widget: the object which received the signal
1924
   * @drag_context: the drag context
1925
   * @data: the #GtkSelectionData to be filled with the dragged data
1926
   * @info: the info that has been registered with the target in the 
1927
   *        #GtkTargetList
1928
   * @time: the timestamp at which the data was requested
1929
   *
1930
   * The ::drag-data-get signal is emitted on the drag source when the drop 
1931
   * site requests the data which is dragged. It is the responsibility of 
1932
   * the signal handler to fill @data with the data in the format which 
1933
   * is indicated by @info. See gtk_selection_data_set() and 
1934
   * gtk_selection_data_set_text().
1935
   */
1936
  widget_signals[DRAG_DATA_GET] =
1937
    g_signal_new (I_("drag-data-get"),
1938
		  G_TYPE_FROM_CLASS (gobject_class),
1939
		  G_SIGNAL_RUN_LAST,
1940
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_get),
1941
		  NULL, NULL,
1942
		  _gtk_marshal_VOID__OBJECT_BOXED_UINT_UINT,
1943
		  G_TYPE_NONE, 4,
1944
		  GDK_TYPE_DRAG_CONTEXT,
1945
		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
1946
		  G_TYPE_UINT,
1947
		  G_TYPE_UINT);
1948
1949
  /**
1950
   * GtkWidget::drag-data-received:
1951
   * @widget: the object which received the signal
1952
   * @drag_context: the drag context
1953
   * @x: where the drop happened
1954
   * @y: where the drop happened
1955
   * @data: the received data
1956
   * @info: the info that has been registered with the target in the 
1957
   *        #GtkTargetList
1958
   * @time: the timestamp at which the data was received
1959
   *
1960
   * The ::drag-data-received signal is emitted on the drop site when the 
1961
   * dragged data has been received. If the data was received in order to 
1962
   * determine whether the drop will be accepted, the handler is expected 
1963
   * to call gdk_drag_status() and <emphasis>not</emphasis> finish the drag. 
1964
   * If the data was received in response to a #GtkWidget::drag-drop signal 
1965
   * (and this is the last target to be received), the handler for this 
1966
   * signal is expected to process the received data and then call 
1967
   * gtk_drag_finish(), setting the @success parameter depending on whether 
1968
   * the data was processed successfully. 
1969
   * 
1970
   * The handler may inspect and modify @drag_context->action before calling 
1971
   * gtk_drag_finish(), e.g. to implement %GDK_ACTION_ASK as shown in the 
1972
   * following example:
1973
   * |[
1974
   * void  
1975
   * drag_data_received (GtkWidget          *widget,
1976
   *                     GdkDragContext     *drag_context,
1977
   *                     gint                x,
1978
   *                     gint                y,
1979
   *                     GtkSelectionData   *data,
1980
   *                     guint               info,
1981
   *                     guint               time)
1982
   * {
1983
   *   if ((data->length >= 0) && (data->format == 8))
1984
   *     {
1985
   *       if (drag_context->action == GDK_ACTION_ASK) 
1986
   *         {
1987
   *           GtkWidget *dialog;
1988
   *           gint response;
1989
   *           
1990
   *           dialog = gtk_message_dialog_new (NULL,
1991
   *                                            GTK_DIALOG_MODAL | 
1992
   *                                            GTK_DIALOG_DESTROY_WITH_PARENT,
1993
   *                                            GTK_MESSAGE_INFO,
1994
   *                                            GTK_BUTTONS_YES_NO,
1995
   *                                            "Move the data ?\n");
1996
   *           response = gtk_dialog_run (GTK_DIALOG (dialog));
1997
   *           gtk_widget_destroy (dialog);
1998
   *             
1999
   *           if (response == GTK_RESPONSE_YES)
2000
   *             drag_context->action = GDK_ACTION_MOVE;
2001
   *           else
2002
   *             drag_context->action = GDK_ACTION_COPY;
2003
   *          }
2004
   *          
2005
   *       gtk_drag_finish (drag_context, TRUE, FALSE, time);
2006
   *       return;
2007
   *     }
2008
   *       
2009
   *    gtk_drag_finish (drag_context, FALSE, FALSE, time);
2010
   *  }
2011
   * ]|
2012
   */
2013
  widget_signals[DRAG_DATA_RECEIVED] =
2014
    g_signal_new (I_("drag-data-received"),
2015
		  G_TYPE_FROM_CLASS (gobject_class),
2016
		  G_SIGNAL_RUN_LAST,
2017
		  G_STRUCT_OFFSET (GtkWidgetClass, drag_data_received),
2018
		  NULL, NULL,
2019
		  _gtk_marshal_VOID__OBJECT_INT_INT_BOXED_UINT_UINT,
2020
		  G_TYPE_NONE, 6,
2021
		  GDK_TYPE_DRAG_CONTEXT,
2022
		  G_TYPE_INT,
2023
		  G_TYPE_INT,
2024
		  GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
2025
		  G_TYPE_UINT,
2026
		  G_TYPE_UINT);
2027
  
2028
  /**
2029
   * GtkWidget::visibility-notify-event:
2030
   * @widget: the object which received the signal
2031
   * @event: the #GdkEventVisibility which triggered this signal
2032
   *
2033
   * The ::visibility-notify-event will be emitted when the @widget's window
2034
   * is obscured or unobscured.
2035
   *
2036
   * To receive this signal the #GdkWindow associated to the widget needs
2037
   * to enable the #GDK_VISIBILITY_NOTIFY_MASK mask.
2038
   *
2039
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
2040
   *   %FALSE to propagate the event further.
2041
   */
2042
  widget_signals[VISIBILITY_NOTIFY_EVENT] =
2043
    g_signal_new (I_("visibility-notify-event"),
2044
		  G_TYPE_FROM_CLASS (gobject_class),
2045
		  G_SIGNAL_RUN_LAST,
2046
		  G_STRUCT_OFFSET (GtkWidgetClass, visibility_notify_event),
2047
		  _gtk_boolean_handled_accumulator, NULL,
2048
		  _gtk_marshal_BOOLEAN__BOXED,
2049
		  G_TYPE_BOOLEAN, 1,
2050
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2051
2052
  /**
2053
   * GtkWidget::client-event:
2054
   * @widget: the object which received the signal
2055
   * @event: the #GdkEventClient which triggered this signal
2056
   *
2057
   * The ::client-event will be emitted when the @widget's window
2058
   * receives a message (via a ClientMessage event) from another
2059
   * application.
2060
   *
2061
   * Returns: %TRUE to stop other handlers from being invoked for 
2062
   *   the event. %FALSE to propagate the event further.
2063
   */
2064
  widget_signals[CLIENT_EVENT] =
2065
    g_signal_new (I_("client-event"),
2066
		  G_TYPE_FROM_CLASS (gobject_class),
2067
		  G_SIGNAL_RUN_LAST,
2068
		  G_STRUCT_OFFSET (GtkWidgetClass, client_event),
2069
		  _gtk_boolean_handled_accumulator, NULL,
2070
		  _gtk_marshal_BOOLEAN__BOXED,
2071
		  G_TYPE_BOOLEAN, 1,
2072
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2073
2074
  /**
2075
   * GtkWidget::no-expose-event:
2076
   * @widget: the object which received the signal
2077
   * @event: the #GdkEventNoExpose which triggered this signal
2078
   *
2079
   * The ::no-expose-event will be emitted when the @widget's window is 
2080
   * drawn as a copy of another #GdkDrawable (with gdk_draw_drawable() or
2081
   * gdk_window_copy_area()) which was completely unobscured. If the source
2082
   * window was partially obscured #GdkEventExpose events will be generated
2083
   * for those areas.
2084
   *
2085
   * Returns: %TRUE to stop other handlers from being invoked for the event. 
2086
   *   %FALSE to propagate the event further.
2087
   */
2088
  widget_signals[NO_EXPOSE_EVENT] =
2089
    g_signal_new (I_("no-expose-event"),
2090
		  G_TYPE_FROM_CLASS (gobject_class),
2091
		  G_SIGNAL_RUN_LAST,
2092
		  G_STRUCT_OFFSET (GtkWidgetClass, no_expose_event),
2093
		  _gtk_boolean_handled_accumulator, NULL,
2094
		  _gtk_marshal_BOOLEAN__BOXED,
2095
		  G_TYPE_BOOLEAN, 1,
2096
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2097
2098
  /**
2099
   * GtkWidget::window-state-event:
2100
   * @widget: the object which received the signal
2101
   * @event: the #GdkEventWindowState which triggered this signal
2102
   *
2103
   * The ::window-state-event will be emitted when the state of the 
2104
   * toplevel window associated to the @widget changes.
2105
   *
2106
   * To receive this signal the #GdkWindow associated to the widget 
2107
   * needs to enable the #GDK_STRUCTURE_MASK mask. GDK will enable 
2108
   * this mask automatically for all new windows.
2109
   *
2110
   * Returns: %TRUE to stop other handlers from being invoked for the 
2111
   *   event. %FALSE to propagate the event further.
2112
   */
2113
  widget_signals[WINDOW_STATE_EVENT] =
2114
    g_signal_new (I_("window-state-event"),
2115
		  G_TYPE_FROM_CLASS (gobject_class),
2116
		  G_SIGNAL_RUN_LAST,
2117
		  G_STRUCT_OFFSET (GtkWidgetClass, window_state_event),
2118
		  _gtk_boolean_handled_accumulator, NULL,
2119
		  _gtk_marshal_BOOLEAN__BOXED,
2120
		  G_TYPE_BOOLEAN, 1,
2121
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2122
2123
  /**
2124
   * GtkWidget::damage-event:
2125
   * @widget: the object which received the signal
2126
   * @event: the #GdkEventExpose event
2127
   *
2128
   * Emitted when a redirected window belonging to @widget gets drawn into.
2129
   * The region/area members of the event shows what area of the redirected
2130
   * drawable was drawn into.
2131
   *
2132
   * Returns: %TRUE to stop other handlers from being invoked for the event.
2133
   *   %FALSE to propagate the event further.
2134
   *
2135
   * Since: 2.14
2136
   */
2137
  widget_signals[DAMAGE_EVENT] =
2138
    g_signal_new (I_("damage-event"),
2139
		  G_TYPE_FROM_CLASS (gobject_class),
2140
		  G_SIGNAL_RUN_LAST,
2141
                  0,
2142
		  _gtk_boolean_handled_accumulator, NULL,
2143
		  _gtk_marshal_BOOLEAN__BOXED,
2144
		  G_TYPE_BOOLEAN, 1,
2145
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2146
/**
2147
   * GtkWidget::grab-broken-event:
2148
   * @widget: the object which received the signal
2149
   * @event: the #GdkEventGrabBroken event
2150
   *
2151
   * Emitted when a pointer or keyboard grab on a window belonging 
2152
   * to @widget gets broken. 
2153
   * 
2154
   * On X11, this happens when the grab window becomes unviewable 
2155
   * (i.e. it or one of its ancestors is unmapped), or if the same 
2156
   * application grabs the pointer or keyboard again.
2157
   *
2158
   * Returns: %TRUE to stop other handlers from being invoked for 
2159
   *   the event. %FALSE to propagate the event further.
2160
   *
2161
   * Since: 2.8
2162
   */
2163
  widget_signals[GRAB_BROKEN] =
2164
    g_signal_new (I_("grab-broken-event"),
2165
		  G_TYPE_FROM_CLASS (gobject_class),
2166
		  G_SIGNAL_RUN_LAST,
2167
		  G_STRUCT_OFFSET (GtkWidgetClass, grab_broken_event),
2168
		  _gtk_boolean_handled_accumulator, NULL,
2169
		  _gtk_marshal_BOOLEAN__BOXED,
2170
		  G_TYPE_BOOLEAN, 1,
2171
		  GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
2172
  /**
2173
   * GtkWidget::query-tooltip:
2174
   * @widget: the object which received the signal
2175
   * @x: the x coordinate of the cursor position where the request has 
2176
   *     been emitted, relative to @widget->window
2177
   * @y: the y coordinate of the cursor position where the request has 
2178
   *     been emitted, relative to @widget->window
2179
   * @keyboard_mode: %TRUE if the tooltip was trigged using the keyboard
2180
   * @tooltip: a #GtkTooltip
2181
   *
2182
   * Emitted when the #GtkSettings:gtk-tooltip-timeout has expired with 
2183
   * the cursor hovering "above" @widget; or emitted when @widget got 
2184
   * focus in keyboard mode.
2185
   *
2186
   * Using the given coordinates, the signal handler should determine
2187
   * whether a tooltip should be shown for @widget. If this is the case
2188
   * %TRUE should be returned, %FALSE otherwise.  Note that if
2189
   * @keyboard_mode is %TRUE, the values of @x and @y are undefined and
2190
   * should not be used.
2191
   *
2192
   * The signal handler is free to manipulate @tooltip with the therefore
2193
   * destined function calls.
2194
   *
2195
   * Returns: %TRUE if @tooltip should be shown right now, %FALSE otherwise.
2196
   *
2197
   * Since: 2.12
2198
   */
2199
  widget_signals[QUERY_TOOLTIP] =
2200
    g_signal_new (I_("query-tooltip"),
2201
		  G_TYPE_FROM_CLASS (gobject_class),
2202
		  G_SIGNAL_RUN_LAST,
2203
		  G_STRUCT_OFFSET (GtkWidgetClass, query_tooltip),
2204
		  _gtk_boolean_handled_accumulator, NULL,
2205
		  _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT,
2206
		  G_TYPE_BOOLEAN, 4,
2207
		  G_TYPE_INT,
2208
		  G_TYPE_INT,
2209
		  G_TYPE_BOOLEAN,
2210
		  GTK_TYPE_TOOLTIP);
2211
2212
  /**
2213
   * GtkWidget::popup-menu
2214
   * @widget: the object which received the signal
2215
   *
2216
   * This signal gets emitted whenever a widget should pop up a context 
2217
   * menu. This usually happens through the standard key binding mechanism; 
2218
   * by pressing a certain key while a widget is focused, the user can cause 
2219
   * the widget to pop up a menu.  For example, the #GtkEntry widget creates 
2220
   * a menu with clipboard commands. See <xref linkend="checklist-popup-menu"/> 
2221
   * for an example of how to use this signal.
2222
   *
2223
   * Returns: %TRUE if a menu was activated
2224
   */
2225
  widget_signals[POPUP_MENU] =
2226
    g_signal_new (I_("popup-menu"),
2227
		  G_TYPE_FROM_CLASS (gobject_class),
2228
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
2229
		  G_STRUCT_OFFSET (GtkWidgetClass, popup_menu),
2230
		  _gtk_boolean_handled_accumulator, NULL,
2231
		  _gtk_marshal_BOOLEAN__VOID,
2232
		  G_TYPE_BOOLEAN, 0);
2233
  widget_signals[SHOW_HELP] =
2234
    g_signal_new (I_("show-help"),
2235
		  G_TYPE_FROM_CLASS (gobject_class),
2236
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
2237
		  G_STRUCT_OFFSET (GtkWidgetClass, show_help),
2238
		  _gtk_boolean_handled_accumulator, NULL,
2239
		  _gtk_marshal_BOOLEAN__ENUM,
2240
		  G_TYPE_BOOLEAN, 1,
2241
		  GTK_TYPE_WIDGET_HELP_TYPE);
2242
  widget_signals[ACCEL_CLOSURES_CHANGED] =
2243
    g_signal_new (I_("accel-closures-changed"),
2244
		  G_TYPE_FROM_CLASS (gobject_class),
2245
		  0,
2246
		  0,
2247
		  NULL, NULL,
2248
		  _gtk_marshal_VOID__VOID,
2249
		  G_TYPE_NONE, 0);
2250
2251
  /**
2252
   * GtkWidget::screen-changed:
2253
   * @widget: the object on which the signal is emitted
2254
   * @previous_screen: the previous screen, or %NULL if the
2255
   *   widget was not associated with a screen before
2256
   *
2257
   * The ::screen-changed signal gets emitted when the
2258
   * screen of a widget has changed.
2259
   */
2260
  widget_signals[SCREEN_CHANGED] =
2261
    g_signal_new (I_("screen-changed"),
2262
		  G_TYPE_FROM_CLASS (gobject_class),
2263
		  G_SIGNAL_RUN_LAST,
2264
		  G_STRUCT_OFFSET (GtkWidgetClass, screen_changed),
2265
		  NULL, NULL,
2266
		  _gtk_marshal_VOID__OBJECT,
2267
		  G_TYPE_NONE, 1,
2268
		  GDK_TYPE_SCREEN);
2269
  /**
2270
   * GtkWidget::can-activate-accel:
2271
   * @widget: the object which received the signal
2272
   * @signal_id: the ID of a signal installed on @widget
2273
   *
2274
   * Determines whether an accelerator that activates the signal
2275
   * identified by @signal_id can currently be activated.
2276
   * This signal is present to allow applications and derived
2277
   * widgets to override the default #GtkWidget handling
2278
   * for determining whether an accelerator can be activated.
2279
   *
2280
   * Returns: %TRUE if the signal can be activated.
2281
   */
2282
  widget_signals[CAN_ACTIVATE_ACCEL] =
2283
     g_signal_new (I_("can-activate-accel"),
2284
		  G_TYPE_FROM_CLASS (gobject_class),
2285
		  G_SIGNAL_RUN_LAST,
2286
		  G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
2287
                  _gtk_boolean_handled_accumulator, NULL,
2288
		  _gtk_marshal_BOOLEAN__UINT,
2289
                  G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
2290
2291
#ifdef MAEMO_CHANGES
2292
  /**
2293
   * GtkWidget::insensitive-press:
2294
   * @widget: the object which received the signal
2295
   *
2296
   * If a widget is insensitive and it receives click event,
2297
   * the signal is emited.  Signal is made to clarify situations where
2298
   * a widget is not easily noticable as an insensitive widget.
2299
   *
2300
   * Deprecated: Use hildon_helper_set_insensitive_message() instead.
2301
   *
2302
   * Since: maemo 1.0
2303
   * Stability: Unstable
2304
   */
2305
  widget_signals[INSENSITIVE_PRESS] =
2306
    g_signal_new ("insensitive_press",
2307
                  G_TYPE_FROM_CLASS (gobject_class),
2308
                  G_SIGNAL_RUN_FIRST,
2309
                  0,
2310
                  NULL, NULL,
2311
                  _gtk_marshal_VOID__VOID,
2312
                  G_TYPE_NONE, 0);
2313
  /**
2314
   * GtkWidget::tap-and-hold:
2315
   * @widget: the object which received the signal
2316
   *
2317
   * The signal is emited when tap and hold activity occurs.
2318
   *
2319
   * Since: maemo 1.0
2320
   * Stability: Unstable
2321
   */
2322
  widget_signals[TAP_AND_HOLD] =
2323
    g_signal_new_class_handler ("tap_and_hold",
2324
                                G_TYPE_FROM_CLASS (gobject_class),
2325
                                G_SIGNAL_RUN_LAST,
2326
                                G_CALLBACK (gtk_widget_real_tap_and_hold),
2327
                                NULL, NULL,
2328
                                _gtk_marshal_VOID__VOID,
2329
                                G_TYPE_NONE, 0);
2330
  /**
2331
   * GtkWidget::tap-and-hold-setup:
2332
   * @widget: the object which received the signal
2333
   * @menu: the menu to be opened.
2334
   * @func: the menu position function
2335
   * @flags: deprecated
2336
   *
2337
   * Enables the tap and hold functionality to the @widget.
2338
   * Usually a @menu is used at tap and hold signal,
2339
   * but this is optional.  Setup can be run and some other functionality
2340
   * may be connected to it as well.  Usually this signal is not used,
2341
   * instead the virtual function is over written.
2342
   *
2343
   * Since: maemo 1.0
2344
   * Stability: Unstable
2345
   */
2346
  widget_signals[TAP_AND_HOLD_SETUP] =
2347
    g_signal_new_class_handler ("tap_and_hold_setup",
2348
                                G_TYPE_FROM_CLASS (gobject_class),
2349
                                G_SIGNAL_RUN_LAST,
2350
                                G_CALLBACK (gtk_widget_real_tap_and_hold_setup),
2351
                                NULL, NULL,
2352
                                /*FIXME -- OBJECT_POINTER_FLAGS*/
2353
                                _gtk_marshal_VOID__OBJECT_UINT_FLAGS,
2354
                                G_TYPE_NONE, 3,
2355
                                G_TYPE_OBJECT,
2356
                                G_TYPE_POINTER,
2357
                                G_TYPE_UINT);
2358
2359
  /**
2360
   * GtkWidget::tap-and-hold-query:
2361
   * @widget: the object which received the signal
2362
   * @returns: %FALSE if tap and hold is allowed to be started
2363
   *
2364
   * Signal is used in a situation where tap and hold is not allowed to be
2365
   * started in some mysterious reason.  A good mysterious reason could be,
2366
   * a widget which area is big and only part of it is allowed to start
2367
   * tap and hold.
2368
   *
2369
   * Since: maemo 1.0
2370
   * Stability: Unstable
2371
   */
2372
  widget_signals[TAP_AND_HOLD_QUERY] =
2373
    g_signal_new_class_handler ("tap_and_hold_query",
2374
                                G_TYPE_FROM_CLASS (gobject_class),
2375
                                G_SIGNAL_RUN_LAST,
2376
                                G_CALLBACK (gtk_widget_real_tap_and_hold_query),
2377
                                gtk_widget_tap_and_hold_query_accumulator, NULL,
2378
                                _gtk_marshal_BOOLEAN__BOXED,
2379
                                G_TYPE_BOOLEAN, 1,
2380
                                GDK_TYPE_EVENT);
2381
#endif /* MAEMO_CHANGES */
2382
2383
  binding_set = gtk_binding_set_by_class (klass);
2384
  gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
2385
                                "popup-menu", 0);
2386
  gtk_binding_entry_add_signal (binding_set, GDK_Menu, 0,
2387
                                "popup-menu", 0);  
2388
2389
  gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_CONTROL_MASK,
2390
                                "show-help", 1,
2391
                                GTK_TYPE_WIDGET_HELP_TYPE,
2392
                                GTK_WIDGET_HELP_TOOLTIP);
2393
  gtk_binding_entry_add_signal (binding_set, GDK_KP_F1, GDK_CONTROL_MASK,
2394
                                "show-help", 1,
2395
                                GTK_TYPE_WIDGET_HELP_TYPE,
2396
                                GTK_WIDGET_HELP_TOOLTIP);
2397
  gtk_binding_entry_add_signal (binding_set, GDK_F1, GDK_SHIFT_MASK,
2398
                                "show-help", 1,
2399
                                GTK_TYPE_WIDGET_HELP_TYPE,
2400
                                GTK_WIDGET_HELP_WHATS_THIS);  
2401
  gtk_binding_entry_add_signal (binding_set, GDK_KP_F1, GDK_SHIFT_MASK,
2402
                                "show-help", 1,
2403
                                GTK_TYPE_WIDGET_HELP_TYPE,
2404
                                GTK_WIDGET_HELP_WHATS_THIS);
2405
2406
  gtk_widget_class_install_style_property (klass,
2407
					   g_param_spec_boolean ("interior-focus",
2408
								 P_("Interior Focus"),
2409
								 P_("Whether to draw the focus indicator inside widgets"),
2410
								 TRUE,
2411
								 GTK_PARAM_READABLE));
2412
2413
#ifdef MAEMO_CHANGES
2414
  gtk_widget_class_install_style_property (klass,
2415
					   g_param_spec_boolean ("maemo-position-theming",
2416
								 P_("Maemo position theming"),
2417
								 P_("Theming hint to allow rounded corner effects on border children"),
2418
								 FALSE,
2419
								 GTK_PARAM_READABLE));
2420
#endif
2421
2422
2423
  gtk_widget_class_install_style_property (klass,
2424
					   g_param_spec_int ("focus-line-width",
2425
							     P_("Focus linewidth"),
2426
							     P_("Width, in pixels, of the focus indicator line"),
2427
							     0, G_MAXINT, 1,
2428
							     GTK_PARAM_READABLE));
2429
2430
  gtk_widget_class_install_style_property (klass,
2431
					   g_param_spec_string ("focus-line-pattern",
2432
								P_("Focus line dash pattern"),
2433
								P_("Dash pattern used to draw the focus indicator"),
2434
								"\1\1",
2435
								GTK_PARAM_READABLE));
2436
  gtk_widget_class_install_style_property (klass,
2437
					   g_param_spec_int ("focus-padding",
2438
							     P_("Focus padding"),
2439
							     P_("Width, in pixels, between focus indicator and the widget 'box'"),
2440
							     0, G_MAXINT, 1,
2441
							     GTK_PARAM_READABLE));
2442
  gtk_widget_class_install_style_property (klass,
2443
					   g_param_spec_boxed ("cursor-color",
2444
							       P_("Cursor color"),
2445
							       P_("Color with which to draw insertion cursor"),
2446
							       GDK_TYPE_COLOR,
2447
							       GTK_PARAM_READABLE));
2448
  gtk_widget_class_install_style_property (klass,
2449
					   g_param_spec_boxed ("secondary-cursor-color",
2450
							       P_("Secondary cursor color"),
2451
							       P_("Color with which to draw the secondary insertion cursor when editing mixed right-to-left and left-to-right text"),
2452
							       GDK_TYPE_COLOR,
2453
							       GTK_PARAM_READABLE));
2454
  gtk_widget_class_install_style_property (klass,
2455
					   g_param_spec_float ("cursor-aspect-ratio",
2456
							       P_("Cursor line aspect ratio"),
2457
							       P_("Aspect ratio with which to draw insertion cursor"),
2458
							       0.0, 1.0, 0.04,
2459
							       GTK_PARAM_READABLE));
2460
2461
  /**
2462
   * GtkWidget:draw-border:
2463
   *
2464
   * The "draw-border" style property defines the size of areas outside 
2465
   * the widget's allocation to draw.
2466
   *
2467
   * Since: 2.8
2468
   */
2469
  gtk_widget_class_install_style_property (klass,
2470
					   g_param_spec_boxed ("draw-border",
2471
							       P_("Draw Border"),
2472
							       P_("Size of areas outside the widget's allocation to draw"),
2473
							       GTK_TYPE_BORDER,
2474
							       GTK_PARAM_READABLE));
2475
2476
  /**
2477
   * GtkWidget:link-color:
2478
   *
2479
   * The "link-color" style property defines the color of unvisited links.
2480
   *
2481
   * Since: 2.10
2482
   */
2483
  gtk_widget_class_install_style_property (klass,
2484
					   g_param_spec_boxed ("link-color",
2485
							       P_("Unvisited Link Color"),
2486
							       P_("Color of unvisited links"),
2487
							       GDK_TYPE_COLOR,
2488
							       GTK_PARAM_READABLE));
2489
2490
  /**
2491
   * GtkWidget:visited-link-color:
2492
   *
2493
   * The "visited-link-color" style property defines the color of visited links.
2494
   *
2495
   * Since: 2.10
2496
   */
2497
  gtk_widget_class_install_style_property (klass,
2498
					   g_param_spec_boxed ("visited-link-color",
2499
							       P_("Visited Link Color"),
2500
							       P_("Color of visited links"),
2501
							       GDK_TYPE_COLOR,
2502
							       GTK_PARAM_READABLE));
2503
2504
  /**
2505
   * GtkWidget:wide-separators:
2506
   *
2507
   * The "wide-separators" style property defines whether separators have 
2508
   * configurable width and should be drawn using a box instead of a line.
2509
   *
2510
   * Since: 2.10
2511
   */
2512
  gtk_widget_class_install_style_property (klass,
2513
                                           g_param_spec_boolean ("wide-separators",
2514
                                                                 P_("Wide Separators"),
2515
                                                                 P_("Whether separators have configurable width and should be drawn using a box instead of a line"),
2516
                                                                 FALSE,
2517
                                                                 GTK_PARAM_READABLE));
2518
2519
  /**
2520
   * GtkWidget:separator-width:
2521
   *
2522
   * The "separator-width" style property defines the width of separators.
2523
   * This property only takes effect if #GtkWidget:wide-separators is %TRUE.
2524
   *
2525
   * Since: 2.10
2526
   */
2527
  gtk_widget_class_install_style_property (klass,
2528
                                           g_param_spec_int ("separator-width",
2529
                                                             P_("Separator Width"),
2530
                                                             P_("The width of separators if wide-separators is TRUE"),
2531
                                                             0, G_MAXINT, 0,
2532
                                                             GTK_PARAM_READABLE));
2533
2534
  /**
2535
   * GtkWidget:separator-height:
2536
   *
2537
   * The "separator-height" style property defines the height of separators.
2538
   * This property only takes effect if #GtkWidget:wide-separators is %TRUE.
2539
   *
2540
   * Since: 2.10
2541
   */
2542
  gtk_widget_class_install_style_property (klass,
2543
                                           g_param_spec_int ("separator-height",
2544
                                                             P_("Separator Height"),
2545
                                                             P_("The height of separators if \"wide-separators\" is TRUE"),
2546
                                                             0, G_MAXINT, 0,
2547
                                                             GTK_PARAM_READABLE));
2548
2549
  /**
2550
   * GtkWidget:scroll-arrow-hlength:
2551
   *
2552
   * The "scroll-arrow-hlength" style property defines the length of 
2553
   * horizontal scroll arrows.
2554
   *
2555
   * Since: 2.10
2556
   */
2557
  gtk_widget_class_install_style_property (klass,
2558
                                           g_param_spec_int ("scroll-arrow-hlength",
2559
                                                             P_("Horizontal Scroll Arrow Length"),
2560
                                                             P_("The length of horizontal scroll arrows"),
2561
                                                             1, G_MAXINT, 16,
2562
                                                             GTK_PARAM_READABLE));
2563
2564
  /**
2565
   * GtkWidget:scroll-arrow-vlength:
2566
   *
2567
   * The "scroll-arrow-vlength" style property defines the length of 
2568
   * vertical scroll arrows.
2569
   *
2570
   * Since: 2.10
2571
   */
2572
  gtk_widget_class_install_style_property (klass,
2573
                                           g_param_spec_int ("scroll-arrow-vlength",
2574
                                                             P_("Vertical Scroll Arrow Length"),
2575
                                                             P_("The length of vertical scroll arrows"),
2576
                                                             1, G_MAXINT, 16,
2577
                                                             GTK_PARAM_READABLE));
2578
2579
#ifdef MAEMO_CHANGES
2580
  gtk_widget_class_install_style_property (klass,
2581
                                           g_param_spec_enum ("hildon-mode",
2582
                                                              P_("Hildon Mode"),
2583
                                                              P_("The mode according to which widgets should behave"),
2584
                                                              HILDON_TYPE_MODE,
2585
                                                              HILDON_DIABLO,
2586
                                                              GTK_PARAM_READABLE));
2587
#endif /* MAEMO_CHANGES */
2588
}
2589
2590
static void
2591
gtk_widget_base_class_finalize (GtkWidgetClass *klass)
2592
{
2593
  GList *list, *node;
2594
2595
  list = g_param_spec_pool_list_owned (style_property_spec_pool, G_OBJECT_CLASS_TYPE (klass));
2596
  for (node = list; node; node = node->next)
2597
    {
2598
      GParamSpec *pspec = node->data;
2599
2600
      g_param_spec_pool_remove (style_property_spec_pool, pspec);
2601
      g_param_spec_unref (pspec);
2602
    }
2603
  g_list_free (list);
2604
}
2605
2606
static void
2607
gtk_widget_set_property (GObject         *object,
2608
			 guint            prop_id,
2609
			 const GValue    *value,
2610
			 GParamSpec      *pspec)
2611
{
2612
  GtkWidget *widget = GTK_WIDGET (object);
2613
2614
  switch (prop_id)
2615
    {
2616
      gboolean tmp;
2617
      guint32 saved_flags;
2618
      gchar *tooltip_markup;
2619
      const gchar *tooltip_text;
2620
      GtkWindow *tooltip_window;
2621
      
2622
    case PROP_NAME:
2623
      gtk_widget_set_name (widget, g_value_get_string (value));
2624
      break;
2625
    case PROP_PARENT:
2626
      gtk_container_add (GTK_CONTAINER (g_value_get_object (value)), widget);
2627
      break;
2628
    case PROP_WIDTH_REQUEST:
2629
      gtk_widget_set_usize_internal (widget, g_value_get_int (value), -2);
2630
      break;
2631
    case PROP_HEIGHT_REQUEST:
2632
      gtk_widget_set_usize_internal (widget, -2, g_value_get_int (value));
2633
      break;
2634
    case PROP_VISIBLE:
2635
      if (g_value_get_boolean (value))
2636
	gtk_widget_show (widget);
2637
      else
2638
	gtk_widget_hide (widget);
2639
      break;
2640
    case PROP_SENSITIVE:
2641
      gtk_widget_set_sensitive (widget, g_value_get_boolean (value));
2642
      break;
2643
    case PROP_APP_PAINTABLE:
2644
      gtk_widget_set_app_paintable (widget, g_value_get_boolean (value));
2645
      break;
2646
    case PROP_CAN_FOCUS:
2647
      saved_flags = GTK_WIDGET_FLAGS (widget);
2648
      if (g_value_get_boolean (value))
2649
	GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
2650
      else
2651
	GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
2652
      if (saved_flags != GTK_WIDGET_FLAGS (widget))
2653
	gtk_widget_queue_resize (widget);
2654
      break;
2655
    case PROP_HAS_FOCUS:
2656
      if (g_value_get_boolean (value))
2657
	gtk_widget_grab_focus (widget);
2658
      break;
2659
    case PROP_IS_FOCUS:
2660
      if (g_value_get_boolean (value))
2661
	gtk_widget_grab_focus (widget);
2662
      break;
2663
    case PROP_CAN_DEFAULT:
2664
      saved_flags = GTK_WIDGET_FLAGS (widget);
2665
      if (g_value_get_boolean (value))
2666
	GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
2667
      else
2668
	GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_DEFAULT);
2669
      if (saved_flags != GTK_WIDGET_FLAGS (widget))
2670
	gtk_widget_queue_resize (widget);
2671
      break;
2672
    case PROP_HAS_DEFAULT:
2673
      if (g_value_get_boolean (value))
2674
	gtk_widget_grab_default (widget);
2675
      break;
2676
    case PROP_RECEIVES_DEFAULT:
2677
      if (g_value_get_boolean (value))
2678
	GTK_WIDGET_SET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
2679
      else
2680
	GTK_WIDGET_UNSET_FLAGS (widget, GTK_RECEIVES_DEFAULT);
2681
      break;
2682
    case PROP_STYLE:
2683
      gtk_widget_set_style (widget, g_value_get_object (value));
2684
      break;
2685
    case PROP_EVENTS:
2686
      if (!GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget))
2687
	gtk_widget_set_events (widget, g_value_get_flags (value));
2688
      break;
2689
    case PROP_EXTENSION_EVENTS:
2690
      gtk_widget_set_extension_events (widget, g_value_get_enum (value));
2691
      break;
2692
    case PROP_NO_SHOW_ALL:
2693
      gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
2694
      break;
2695
    case PROP_HAS_TOOLTIP:
2696
      gtk_widget_real_set_has_tooltip (widget,
2697
				       g_value_get_boolean (value), FALSE);
2698
      break;
2699
    case PROP_TOOLTIP_MARKUP:
2700
      tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
2701
      tooltip_markup = g_value_dup_string (value);
2702
2703
      /* Treat an empty string as a NULL string, 
2704
       * because an empty string would be useless for a tooltip:
2705
       */
2706
      if (tooltip_markup && (strlen (tooltip_markup) == 0))
2707
      {
2708
	g_free (tooltip_markup);
2709
        tooltip_markup = NULL;
2710
      }
2711
2712
      g_object_set_qdata_full (object, quark_tooltip_markup,
2713
			       tooltip_markup, g_free);
2714
2715
      tmp = (tooltip_window != NULL || tooltip_markup != NULL);
2716
      gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
2717
      break;
2718
    case PROP_TOOLTIP_TEXT:
2719
      tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
2720
2721
      tooltip_text = g_value_get_string (value);
2722
2723
      /* Treat an empty string as a NULL string, 
2724
       * because an empty string would be useless for a tooltip:
2725
       */
2726
      if (tooltip_text && (strlen (tooltip_text) == 0))
2727
        tooltip_text = NULL;
2728
2729
      tooltip_markup = tooltip_text ? g_markup_escape_text (tooltip_text, -1) : NULL;
2730
2731
      g_object_set_qdata_full (object, quark_tooltip_markup,
2732
                               tooltip_markup, g_free);
2733
2734
      tmp = (tooltip_window != NULL || tooltip_markup != NULL);
2735
      gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
2736
      break;
2737
#ifdef MAEMO_CHANGES
2738
    case PROP_TAP_AND_HOLD:
2739
      break;
2740
#endif /* MAEMO_CHANGES */
2741
    default:
2742
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2743
      break;
2744
    }
2745
}
2746
2747
static void
2748
gtk_widget_get_property (GObject         *object,
2749
			 guint            prop_id,
2750
			 GValue          *value,
2751
			 GParamSpec      *pspec)
2752
{
2753
  GtkWidget *widget = GTK_WIDGET (object);
2754
  
2755
  switch (prop_id)
2756
    {
2757
      gpointer *eventp;
2758
      gpointer *modep;
2759
2760
    case PROP_NAME:
2761
      if (widget->name)
2762
	g_value_set_string (value, widget->name);
2763
      else
2764
	g_value_set_static_string (value, "");
2765
      break;
2766
    case PROP_PARENT:
2767
      if (widget->parent)
2768
	g_value_set_object (value, widget->parent);
2769
      else
2770
	g_value_set_object (value, NULL);
2771
      break;
2772
    case PROP_WIDTH_REQUEST:
2773
      {
2774
        int w;
2775
        gtk_widget_get_size_request (widget, &w, NULL);
2776
        g_value_set_int (value, w);
2777
      }
2778
      break;
2779
    case PROP_HEIGHT_REQUEST:
2780
      {
2781
        int h;
2782
        gtk_widget_get_size_request (widget, NULL, &h);
2783
        g_value_set_int (value, h);
2784
      }
2785
      break;
2786
    case PROP_VISIBLE:
2787
      g_value_set_boolean (value, (GTK_WIDGET_VISIBLE (widget) != FALSE));
2788
      break;
2789
    case PROP_SENSITIVE:
2790
      g_value_set_boolean (value, (GTK_WIDGET_SENSITIVE (widget) != FALSE));
2791
      break;
2792
    case PROP_APP_PAINTABLE:
2793
      g_value_set_boolean (value, (GTK_WIDGET_APP_PAINTABLE (widget) != FALSE));
2794
      break;
2795
    case PROP_CAN_FOCUS:
2796
      g_value_set_boolean (value, (GTK_WIDGET_CAN_FOCUS (widget) != FALSE));
2797
      break;
2798
    case PROP_HAS_FOCUS:
2799
      g_value_set_boolean (value, (GTK_WIDGET_HAS_FOCUS (widget) != FALSE));
2800
      break;
2801
    case PROP_IS_FOCUS:
2802
      g_value_set_boolean (value, (gtk_widget_is_focus (widget)));
2803
      break;
2804
    case PROP_CAN_DEFAULT:
2805
      g_value_set_boolean (value, (GTK_WIDGET_CAN_DEFAULT (widget) != FALSE));
2806
      break;
2807
    case PROP_HAS_DEFAULT:
2808
      g_value_set_boolean (value, (GTK_WIDGET_HAS_DEFAULT (widget) != FALSE));
2809
      break;
2810
    case PROP_RECEIVES_DEFAULT:
2811
      g_value_set_boolean (value, (GTK_WIDGET_RECEIVES_DEFAULT (widget) != FALSE));
2812
      break;
2813
    case PROP_COMPOSITE_CHILD:
2814
      g_value_set_boolean (value, (GTK_WIDGET_COMPOSITE_CHILD (widget) != FALSE));
2815
      break;
2816
    case PROP_STYLE:
2817
      g_value_set_object (value, gtk_widget_get_style (widget));
2818
      break;
2819
    case PROP_EVENTS:
2820
      eventp = g_object_get_qdata (G_OBJECT (widget), quark_event_mask);
2821
      g_value_set_flags (value, GPOINTER_TO_INT (eventp));
2822
      break;
2823
    case PROP_EXTENSION_EVENTS:
2824
      modep = g_object_get_qdata (G_OBJECT (widget), quark_extension_event_mode);
2825
      g_value_set_enum (value, GPOINTER_TO_INT (modep));
2826
      break;
2827
    case PROP_NO_SHOW_ALL:
2828
      g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
2829
      break;
2830
    case PROP_HAS_TOOLTIP:
2831
      g_value_set_boolean (value, GPOINTER_TO_UINT (g_object_get_qdata (object, quark_has_tooltip)));
2832
      break;
2833
    case PROP_TOOLTIP_TEXT:
2834
      {
2835
        gchar *escaped = g_object_get_qdata (object, quark_tooltip_markup);
2836
        gchar *text = NULL;
2837
2838
        if (escaped && !pango_parse_markup (escaped, -1, 0, NULL, &text, NULL, NULL))
2839
          g_assert (NULL == text); /* text should still be NULL in case of markup errors */
2840
2841
        g_value_set_string (value, text);
2842
        g_free (text);
2843
      }
2844
      break;
2845
    case PROP_TOOLTIP_MARKUP:
2846
      g_value_set_string (value, g_object_get_qdata (object, quark_tooltip_markup));
2847
      break;
2848
    case PROP_WINDOW:
2849
      g_value_set_object (value, gtk_widget_get_window (widget));
2850
      break;
2851
#ifdef MAEMO_CHANGES
2852
    case PROP_TAP_AND_HOLD:
2853
      break;
2854
#endif /* MAEMO_CHANGES */
2855
    default:
2856
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2857
      break;
2858
    }
2859
}
2860
2861
static void
2862
gtk_widget_init (GtkWidget *widget)
2863
{
2864
  GTK_PRIVATE_FLAGS (widget) = PRIVATE_GTK_CHILD_VISIBLE;
2865
  widget->state = GTK_STATE_NORMAL;
2866
  widget->saved_state = GTK_STATE_NORMAL;
2867
  widget->name = NULL;
2868
  widget->requisition.width = 0;
2869
  widget->requisition.height = 0;
2870
  widget->allocation.x = -1;
2871
  widget->allocation.y = -1;
2872
  widget->allocation.width = 1;
2873
  widget->allocation.height = 1;
2874
  widget->window = NULL;
2875
  widget->parent = NULL;
2876
2877
  GTK_WIDGET_SET_FLAGS (widget,
2878
			GTK_SENSITIVE |
2879
			GTK_PARENT_SENSITIVE |
2880
			(composite_child_stack ? GTK_COMPOSITE_CHILD : 0) |
2881
			GTK_DOUBLE_BUFFERED);
2882
2883
  GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
2884
  GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
2885
  GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
2886
2887
  widget->style = gtk_widget_get_default_style ();
2888
  g_object_ref (widget->style);
2889
}
2890
2891
2892
static void
2893
gtk_widget_dispatch_child_properties_changed (GtkWidget   *widget,
2894
					      guint        n_pspecs,
2895
					      GParamSpec **pspecs)
2896
{
2897
  GtkWidget *container = widget->parent;
2898
  guint i;
2899
2900
  for (i = 0; widget->parent == container && i < n_pspecs; i++)
2901
    g_signal_emit (widget, widget_signals[CHILD_NOTIFY], g_quark_from_string (pspecs[i]->name), pspecs[i]);
2902
}
2903
2904
/**
2905
 * gtk_widget_freeze_child_notify:
2906
 * @widget: a #GtkWidget
2907
 * 
2908
 * Stops emission of #GtkWidget::child-notify signals on @widget. The 
2909
 * signals are queued until gtk_widget_thaw_child_notify() is called 
2910
 * on @widget. 
2911
 *
2912
 * This is the analogue of g_object_freeze_notify() for child properties.
2913
 **/
2914
void
2915
gtk_widget_freeze_child_notify (GtkWidget *widget)
2916
{
2917
  g_return_if_fail (GTK_IS_WIDGET (widget));
2918
2919
  if (!G_OBJECT (widget)->ref_count)
2920
    return;
2921
2922
  g_object_ref (widget);
2923
  g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
2924
  g_object_unref (widget);
2925
}
2926
2927
/**
2928
 * gtk_widget_child_notify:
2929
 * @widget: a #GtkWidget
2930
 * @child_property: the name of a child property installed on the 
2931
 *                  class of @widget<!-- -->'s parent
2932
 * 
2933
 * Emits a #GtkWidget::child-notify signal for the 
2934
 * <link linkend="child-properties">child property</link> @child_property 
2935
 * on @widget.
2936
 *
2937
 * This is the analogue of g_object_notify() for child properties.
2938
 **/
2939
void
2940
gtk_widget_child_notify (GtkWidget    *widget,
2941
			 const gchar  *child_property)
2942
{
2943
  GParamSpec *pspec;
2944
2945
  g_return_if_fail (GTK_IS_WIDGET (widget));
2946
  g_return_if_fail (child_property != NULL);
2947
  if (!G_OBJECT (widget)->ref_count || !widget->parent)
2948
    return;
2949
2950
  g_object_ref (widget);
2951
  pspec = g_param_spec_pool_lookup (_gtk_widget_child_property_pool,
2952
				    child_property,
2953
				    G_OBJECT_TYPE (widget->parent),
2954
				    TRUE);
2955
  if (!pspec)
2956
    g_warning ("%s: container class `%s' has no child property named `%s'",
2957
	       G_STRLOC,
2958
	       G_OBJECT_TYPE_NAME (widget->parent),
2959
	       child_property);
2960
  else
2961
    {
2962
      GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
2963
2964
      g_object_notify_queue_add (G_OBJECT (widget), nqueue, pspec);
2965
      g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
2966
    }
2967
  g_object_unref (widget);
2968
}
2969
2970
/**
2971
 * gtk_widget_thaw_child_notify:
2972
 * @widget: a #GtkWidget
2973
 *
2974
 * Reverts the effect of a previous call to gtk_widget_freeze_child_notify().
2975
 * This causes all queued #GtkWidget::child-notify signals on @widget to be 
2976
 * emitted.
2977
 */ 
2978
void
2979
gtk_widget_thaw_child_notify (GtkWidget *widget)
2980
{
2981
  GObjectNotifyQueue *nqueue;
2982
2983
  g_return_if_fail (GTK_IS_WIDGET (widget));
2984
2985
  if (!G_OBJECT (widget)->ref_count)
2986
    return;
2987
2988
  g_object_ref (widget);
2989
  nqueue = g_object_notify_queue_from_object (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
2990
  if (!nqueue || !nqueue->freeze_count)
2991
    g_warning (G_STRLOC ": child-property-changed notification for %s(%p) is not frozen",
2992
	       G_OBJECT_TYPE_NAME (widget), widget);
2993
  else
2994
    g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
2995
  g_object_unref (widget);
2996
}
2997
2998
2999
/**
3000
 * gtk_widget_new:
3001
 * @type: type ID of the widget to create
3002
 * @first_property_name: name of first property to set
3003
 * @Varargs: value of first property, followed by more properties, 
3004
 *           %NULL-terminated
3005
 * 
3006
 * This is a convenience function for creating a widget and setting
3007
 * its properties in one go. For example you might write:
3008
 * <literal>gtk_widget_new (GTK_TYPE_LABEL, "label", "Hello World", "xalign",
3009
 * 0.0, NULL)</literal> to create a left-aligned label. Equivalent to
3010
 * g_object_new(), but returns a widget so you don't have to
3011
 * cast the object yourself.
3012
 * 
3013
 * Return value: a new #GtkWidget of type @widget_type
3014
 **/
3015
GtkWidget*
3016
gtk_widget_new (GType        type,
3017
		const gchar *first_property_name,
3018
		...)
3019
{
3020
  GtkWidget *widget;
3021
  va_list var_args;
3022
  
3023
  g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), NULL);
3024
  
3025
  va_start (var_args, first_property_name);
3026
  widget = (GtkWidget *)g_object_new_valist (type, first_property_name, var_args);
3027
  va_end (var_args);
3028
3029
  return widget;
3030
}
3031
3032
/**
3033
 * gtk_widget_set:
3034
 * @widget: a #GtkWidget
3035
 * @first_property_name: name of first property to set
3036
 * @Varargs: value of first property, followed by more properties, 
3037
 *           %NULL-terminated
3038
 * 
3039
 * Precursor of g_object_set().
3040
 *
3041
 * Deprecated: 2.0: Use g_object_set() instead.
3042
 **/
3043
void
3044
gtk_widget_set (GtkWidget   *widget,
3045
		const gchar *first_property_name,
3046
		...)
3047
{
3048
  va_list var_args;
3049
3050
  g_return_if_fail (GTK_IS_WIDGET (widget));
3051
3052
  va_start (var_args, first_property_name);
3053
  g_object_set_valist (G_OBJECT (widget), first_property_name, var_args);
3054
  va_end (var_args);
3055
}
3056
3057
static inline void	   
3058
gtk_widget_queue_draw_child (GtkWidget *widget)
3059
{
3060
  GtkWidget *parent;
3061
3062
  parent = widget->parent;
3063
  if (parent && GTK_WIDGET_DRAWABLE (parent))
3064
    gtk_widget_queue_draw_area (parent,
3065
				widget->allocation.x,
3066
				widget->allocation.y,
3067
				widget->allocation.width,
3068
				widget->allocation.height);
3069
}
3070
3071
/**
3072
 * gtk_widget_unparent:
3073
 * @widget: a #GtkWidget
3074
 * 
3075
 * This function is only for use in widget implementations.
3076
 * Should be called by implementations of the remove method
3077
 * on #GtkContainer, to dissociate a child from the container.
3078
 **/
3079
void
3080
gtk_widget_unparent (GtkWidget *widget)
3081
{
3082
  GObjectNotifyQueue *nqueue;
3083
  GtkWidget *toplevel;
3084
  GtkWidget *old_parent;
3085
  
3086
  g_return_if_fail (GTK_IS_WIDGET (widget));
3087
  if (widget->parent == NULL)
3088
    return;
3089
  
3090
  /* keep this function in sync with gtk_menu_detach()
3091
   */
3092
3093
  g_object_freeze_notify (G_OBJECT (widget));
3094
  nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
3095
3096
  toplevel = gtk_widget_get_toplevel (widget);
3097
  if (GTK_WIDGET_TOPLEVEL (toplevel))
3098
    _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
3099
3100
  if (GTK_CONTAINER (widget->parent)->focus_child == widget)
3101
    gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), NULL);
3102
3103
  /* If we are unanchoring the child, we save around the toplevel
3104
   * to emit hierarchy changed
3105
   */
3106
  if (GTK_WIDGET_ANCHORED (widget->parent))
3107
    g_object_ref (toplevel);
3108
  else
3109
    toplevel = NULL;
3110
3111
  gtk_widget_queue_draw_child (widget);
3112
3113
  /* Reset the width and height here, to force reallocation if we
3114
   * get added back to a new parent. This won't work if our new
3115
   * allocation is smaller than 1x1 and we actually want a size of 1x1...
3116
   * (would 0x0 be OK here?)
3117
   */
3118
  widget->allocation.width = 1;
3119
  widget->allocation.height = 1;
3120
  
3121
  if (GTK_WIDGET_REALIZED (widget)) 
3122
    {
3123
      if (GTK_WIDGET_IN_REPARENT (widget))
3124
	gtk_widget_unmap (widget);
3125
      else
3126
	gtk_widget_unrealize (widget);
3127
    }
3128
3129
  /* Removing a widget from a container restores the child visible
3130
   * flag to the default state, so it doesn't affect the child
3131
   * in the next parent.
3132
   */
3133
  GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
3134
    
3135
  old_parent = widget->parent;
3136
  widget->parent = NULL;
3137
  gtk_widget_set_parent_window (widget, NULL);
3138
  g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
3139
  if (toplevel)
3140
    {
3141
      _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
3142
      g_object_unref (toplevel);
3143
    }
3144
      
3145
  g_object_notify (G_OBJECT (widget), "parent");
3146
  g_object_thaw_notify (G_OBJECT (widget));
3147
  if (!widget->parent)
3148
    g_object_notify_queue_clear (G_OBJECT (widget), nqueue);
3149
  g_object_notify_queue_thaw (G_OBJECT (widget), nqueue);
3150
  g_object_unref (widget);
3151
}
3152
3153
/**
3154
 * gtk_widget_destroy:
3155
 * @widget: a #GtkWidget
3156
 *
3157
 * Destroys a widget. Equivalent to gtk_object_destroy(), except that
3158
 * you don't have to cast the widget to #GtkObject. When a widget is
3159
 * destroyed, it will break any references it holds to other objects.
3160
 * If the widget is inside a container, the widget will be removed
3161
 * from the container. If the widget is a toplevel (derived from
3162
 * #GtkWindow), it will be removed from the list of toplevels, and the
3163
 * reference GTK+ holds to it will be removed. Removing a
3164
 * widget from its container or the list of toplevels results in the
3165
 * widget being finalized, unless you've added additional references
3166
 * to the widget with g_object_ref().
3167
 *
3168
 * In most cases, only toplevel widgets (windows) require explicit
3169
 * destruction, because when you destroy a toplevel its children will
3170
 * be destroyed as well.
3171
 **/
3172
void
3173
gtk_widget_destroy (GtkWidget *widget)
3174
{
3175
  g_return_if_fail (GTK_IS_WIDGET (widget));
3176
3177
  gtk_object_destroy ((GtkObject*) widget);
3178
}
3179
3180
/**
3181
 * gtk_widget_destroyed:
3182
 * @widget: a #GtkWidget
3183
 * @widget_pointer: address of a variable that contains @widget
3184
 *
3185
 * This function sets *@widget_pointer to %NULL if @widget_pointer !=
3186
 * %NULL.  It's intended to be used as a callback connected to the
3187
 * "destroy" signal of a widget. You connect gtk_widget_destroyed()
3188
 * as a signal handler, and pass the address of your widget variable
3189
 * as user data. Then when the widget is destroyed, the variable will
3190
 * be set to %NULL. Useful for example to avoid multiple copies
3191
 * of the same dialog.
3192
 **/
3193
void
3194
gtk_widget_destroyed (GtkWidget      *widget,
3195
		      GtkWidget      **widget_pointer)
3196
{
3197
  /* Don't make any assumptions about the
3198
   *  value of widget!
3199
   *  Even check widget_pointer.
3200
   */
3201
  if (widget_pointer)
3202
    *widget_pointer = NULL;
3203
}
3204
3205
/**
3206
 * gtk_widget_show:
3207
 * @widget: a #GtkWidget
3208
 * 
3209
 * Flags a widget to be displayed. Any widget that isn't shown will
3210
 * not appear on the screen. If you want to show all the widgets in a
3211
 * container, it's easier to call gtk_widget_show_all() on the
3212
 * container, instead of individually showing the widgets.
3213
 *
3214
 * Remember that you have to show the containers containing a widget,
3215
 * in addition to the widget itself, before it will appear onscreen.
3216
 *
3217
 * When a toplevel container is shown, it is immediately realized and
3218
 * mapped; other shown widgets are realized and mapped when their
3219
 * toplevel container is realized and mapped.
3220
 **/
3221
void
3222
gtk_widget_show (GtkWidget *widget)
3223
{
3224
  g_return_if_fail (GTK_IS_WIDGET (widget));
3225
3226
  if (!GTK_WIDGET_VISIBLE (widget))
3227
    {
3228
      g_object_ref (widget);
3229
      if (!GTK_WIDGET_TOPLEVEL (widget))
3230
	gtk_widget_queue_resize (widget);
3231
      g_signal_emit (widget, widget_signals[SHOW], 0);
3232
      g_object_notify (G_OBJECT (widget), "visible");
3233
      g_object_unref (widget);
3234
    }
3235
}
3236
3237
static void
3238
gtk_widget_real_show (GtkWidget *widget)
3239
{
3240
  if (!GTK_WIDGET_VISIBLE (widget))
3241
    {
3242
      GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
3243
3244
      if (widget->parent &&
3245
	  GTK_WIDGET_MAPPED (widget->parent) &&
3246
	  GTK_WIDGET_CHILD_VISIBLE (widget) &&
3247
	  !GTK_WIDGET_MAPPED (widget))
3248
	gtk_widget_map (widget);
3249
    }
3250
}
3251
3252
static void
3253
gtk_widget_show_map_callback (GtkWidget *widget, GdkEvent *event, gint *flag)
3254
{
3255
  *flag = TRUE;
3256
  g_signal_handlers_disconnect_by_func (widget,
3257
					gtk_widget_show_map_callback, 
3258
					flag);
3259
}
3260
3261
/**
3262
 * gtk_widget_show_now:
3263
 * @widget: a #GtkWidget
3264
 * 
3265
 * Shows a widget. If the widget is an unmapped toplevel widget
3266
 * (i.e. a #GtkWindow that has not yet been shown), enter the main
3267
 * loop and wait for the window to actually be mapped. Be careful;
3268
 * because the main loop is running, anything can happen during
3269
 * this function.
3270
 **/
3271
void
3272
gtk_widget_show_now (GtkWidget *widget)
3273
{
3274
  gint flag = FALSE;
3275
  
3276
  g_return_if_fail (GTK_IS_WIDGET (widget));
3277
3278
  /* make sure we will get event */
3279
  if (!GTK_WIDGET_MAPPED (widget) &&
3280
      GTK_WIDGET_TOPLEVEL (widget))
3281
    {
3282
      gtk_widget_show (widget);
3283
3284
      g_signal_connect (widget, "map-event",
3285
			G_CALLBACK (gtk_widget_show_map_callback), 
3286
			&flag);
3287
3288
      while (!flag)
3289
	gtk_main_iteration ();
3290
    }
3291
  else
3292
    gtk_widget_show (widget);
3293
}
3294
3295
/**
3296
 * gtk_widget_hide:
3297
 * @widget: a #GtkWidget
3298
 * 
3299
 * Reverses the effects of gtk_widget_show(), causing the widget to be
3300
 * hidden (invisible to the user).
3301
 **/
3302
void
3303
gtk_widget_hide (GtkWidget *widget)
3304
{
3305
  g_return_if_fail (GTK_IS_WIDGET (widget));
3306
  
3307
  if (GTK_WIDGET_VISIBLE (widget))
3308
    {
3309
      GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
3310
      
3311
      g_object_ref (widget);
3312
      if (toplevel != widget && GTK_WIDGET_TOPLEVEL (toplevel))
3313
	_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
3314
3315
      g_signal_emit (widget, widget_signals[HIDE], 0);
3316
      if (!GTK_WIDGET_TOPLEVEL (widget))
3317
	gtk_widget_queue_resize (widget);
3318
      g_object_notify (G_OBJECT (widget), "visible");
3319
      g_object_unref (widget);
3320
    }
3321
}
3322
3323
static void
3324
gtk_widget_real_hide (GtkWidget *widget)
3325
{
3326
  if (GTK_WIDGET_VISIBLE (widget))
3327
    {
3328
      GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
3329
      
3330
      if (GTK_WIDGET_MAPPED (widget))
3331
	gtk_widget_unmap (widget);
3332
    }
3333
}
3334
3335
/**
3336
 * gtk_widget_hide_on_delete:
3337
 * @widget: a #GtkWidget
3338
 * 
3339
 * Utility function; intended to be connected to the #GtkWidget::delete-event
3340
 * signal on a #GtkWindow. The function calls gtk_widget_hide() on its
3341
 * argument, then returns %TRUE. If connected to ::delete-event, the
3342
 * result is that clicking the close button for a window (on the
3343
 * window frame, top right corner usually) will hide but not destroy
3344
 * the window. By default, GTK+ destroys windows when ::delete-event
3345
 * is received.
3346
 * 
3347
 * Return value: %TRUE
3348
 **/
3349
gboolean
3350
gtk_widget_hide_on_delete (GtkWidget *widget)
3351
{
3352
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
3353
  
3354
  gtk_widget_hide (widget);
3355
  
3356
  return TRUE;
3357
}
3358
3359
/**
3360
 * gtk_widget_show_all:
3361
 * @widget: a #GtkWidget
3362
 * 
3363
 * Recursively shows a widget, and any child widgets (if the widget is
3364
 * a container).
3365
 **/
3366
void
3367
gtk_widget_show_all (GtkWidget *widget)
3368
{
3369
  GtkWidgetClass *class;
3370
3371
  g_return_if_fail (GTK_IS_WIDGET (widget));
3372
3373
  if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
3374
    return;
3375
3376
  class = GTK_WIDGET_GET_CLASS (widget);
3377
3378
  if (class->show_all)
3379
    class->show_all (widget);
3380
}
3381
3382
/**
3383
 * gtk_widget_hide_all:
3384
 * @widget: a #GtkWidget
3385
 * 
3386
 * Recursively hides a widget and any child widgets.
3387
 **/
3388
void
3389
gtk_widget_hide_all (GtkWidget *widget)
3390
{
3391
  GtkWidgetClass *class;
3392
3393
  g_return_if_fail (GTK_IS_WIDGET (widget));
3394
3395
  if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
3396
    return;
3397
3398
  class = GTK_WIDGET_GET_CLASS (widget);
3399
3400
  if (class->hide_all)
3401
    class->hide_all (widget);
3402
}
3403
3404
/**
3405
 * gtk_widget_map:
3406
 * @widget: a #GtkWidget
3407
 * 
3408
 * This function is only for use in widget implementations. Causes
3409
 * a widget to be mapped if it isn't already.
3410
 **/
3411
void
3412
gtk_widget_map (GtkWidget *widget)
3413
{
3414
  g_return_if_fail (GTK_IS_WIDGET (widget));
3415
  g_return_if_fail (GTK_WIDGET_VISIBLE (widget));
3416
  g_return_if_fail (GTK_WIDGET_CHILD_VISIBLE (widget));
3417
  
3418
  if (!GTK_WIDGET_MAPPED (widget))
3419
    {
3420
      if (!GTK_WIDGET_REALIZED (widget))
3421
	gtk_widget_realize (widget);
3422
3423
      g_signal_emit (widget, widget_signals[MAP], 0);
3424
3425
      if (GTK_WIDGET_NO_WINDOW (widget))
3426
	gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
3427
    }
3428
}
3429
3430
/**
3431
 * gtk_widget_unmap:
3432
 * @widget: a #GtkWidget
3433
 *
3434
 * This function is only for use in widget implementations. Causes
3435
 * a widget to be unmapped if it's currently mapped.
3436
 **/
3437
void
3438
gtk_widget_unmap (GtkWidget *widget)
3439
{
3440
  g_return_if_fail (GTK_IS_WIDGET (widget));
3441
  
3442
  if (GTK_WIDGET_MAPPED (widget))
3443
    {
3444
      if (GTK_WIDGET_NO_WINDOW (widget))
3445
	gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
3446
      _gtk_tooltip_hide (widget);
3447
      g_signal_emit (widget, widget_signals[UNMAP], 0);
3448
    }
3449
}
3450
3451
static void
3452
gtk_widget_set_extension_events_internal (GtkWidget        *widget,
3453
                                          GdkExtensionMode  mode,
3454
                                          GList            *window_list)
3455
{
3456
  GList *free_list = NULL;
3457
  GList *l;
3458
3459
  if (window_list == NULL)
3460
    {
3461
      if (!GTK_WIDGET_NO_WINDOW (widget))
3462
        window_list = g_list_prepend (NULL, widget->window);
3463
      else
3464
        window_list = gdk_window_get_children (widget->window);
3465
3466
      free_list = window_list;
3467
    }
3468
3469
  for (l = window_list; l != NULL; l = l->next)
3470
    {
3471
      GdkWindow *window = l->data;
3472
      gpointer user_data;
3473
3474
      gdk_window_get_user_data (window, &user_data);
3475
      if (user_data == widget)
3476
        {
3477
          GList *children;
3478
3479
          gdk_input_set_extension_events (window,
3480
                                          gdk_window_get_events (window),
3481
                                          mode);
3482
3483
          children = gdk_window_get_children (window);
3484
          if (children)
3485
            {
3486
              gtk_widget_set_extension_events_internal (widget, mode, children);
3487
              g_list_free (children);
3488
            }
3489
        }
3490
    }
3491
3492
  if (free_list)
3493
    g_list_free (free_list);
3494
}
3495
3496
/**
3497
 * gtk_widget_realize:
3498
 * @widget: a #GtkWidget
3499
 * 
3500
 * Creates the GDK (windowing system) resources associated with a
3501
 * widget.  For example, @widget->window will be created when a widget
3502
 * is realized.  Normally realization happens implicitly; if you show
3503
 * a widget and all its parent containers, then the widget will be
3504
 * realized and mapped automatically.
3505
 * 
3506
 * Realizing a widget requires all
3507
 * the widget's parent widgets to be realized; calling
3508
 * gtk_widget_realize() realizes the widget's parents in addition to
3509
 * @widget itself. If a widget is not yet inside a toplevel window
3510
 * when you realize it, bad things will happen.
3511
 *
3512
 * This function is primarily used in widget implementations, and
3513
 * isn't very useful otherwise. Many times when you think you might
3514
 * need it, a better approach is to connect to a signal that will be
3515
 * called after the widget is realized automatically, such as
3516
 * GtkWidget::expose-event. Or simply g_signal_connect () to the
3517
 * GtkWidget::realize signal.
3518
 **/
3519
void
3520
gtk_widget_realize (GtkWidget *widget)
3521
{
3522
  GdkExtensionMode mode;
3523
  GtkWidgetShapeInfo *shape_info;
3524
  
3525
  g_return_if_fail (GTK_IS_WIDGET (widget));
3526
  g_return_if_fail (GTK_WIDGET_ANCHORED (widget) ||
3527
		    GTK_IS_INVISIBLE (widget));
3528
  
3529
  if (!GTK_WIDGET_REALIZED (widget))
3530
    {
3531
      /*
3532
	if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
3533
	  g_message ("gtk_widget_realize(%s)", g_type_name (GTK_WIDGET_TYPE (widget)));
3534
      */
3535
3536
      if (widget->parent == NULL &&
3537
          !GTK_WIDGET_TOPLEVEL (widget))
3538
        g_warning ("Calling gtk_widget_realize() on a widget that isn't "
3539
                   "inside a toplevel window is not going to work very well. "
3540
                   "Widgets must be inside a toplevel container before realizing them.");
3541
      
3542
      if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
3543
	gtk_widget_realize (widget->parent);
3544
3545
      gtk_widget_ensure_style (widget);
3546
      
3547
      g_signal_emit (widget, widget_signals[REALIZE], 0);
3548
3549
      gtk_widget_real_set_has_tooltip (widget,
3550
				       GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (widget), quark_has_tooltip)),
3551
				       TRUE);
3552
3553
      if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
3554
	{
3555
	  shape_info = g_object_get_qdata (G_OBJECT (widget), quark_shape_info);
3556
	  gdk_window_shape_combine_mask (widget->window,
3557
					 shape_info->shape_mask,
3558
					 shape_info->offset_x,
3559
					 shape_info->offset_y);
3560
	}
3561
      
3562
      shape_info = g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info);
3563
      if (shape_info)
3564
	gdk_window_input_shape_combine_mask (widget->window,
3565
					     shape_info->shape_mask,
3566
					     shape_info->offset_x,
3567
					     shape_info->offset_y);
3568
3569
      mode = gtk_widget_get_extension_events (widget);
3570
      if (mode != GDK_EXTENSION_EVENTS_NONE)
3571
        gtk_widget_set_extension_events_internal (widget, mode, NULL);
3572
    }
3573
}
3574
3575
/**
3576
 * gtk_widget_unrealize:
3577
 * @widget: a #GtkWidget
3578
 *
3579
 * This function is only useful in widget implementations.
3580
 * Causes a widget to be unrealized (frees all GDK resources
3581
 * associated with the widget, such as @widget->window).
3582
 **/
3583
void
3584
gtk_widget_unrealize (GtkWidget *widget)
3585
{
3586
  g_return_if_fail (GTK_IS_WIDGET (widget));
3587
3588
  if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
3589
    gtk_widget_shape_combine_mask (widget, NULL, 0, 0);
3590
3591
  if (g_object_get_qdata (G_OBJECT (widget), quark_input_shape_info))
3592
    gtk_widget_input_shape_combine_mask (widget, NULL, 0, 0);
3593
3594
  if (GTK_WIDGET_REALIZED (widget))
3595
    {
3596
      g_object_ref (widget);
3597
      _gtk_tooltip_hide (widget);
3598
      g_signal_emit (widget, widget_signals[UNREALIZE], 0);
3599
      GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
3600
      g_object_unref (widget);
3601
    }
3602
}
3603
3604
/*****************************************
3605
 * Draw queueing.
3606
 *****************************************/
3607
3608
/**
3609
 * gtk_widget_queue_draw_area:
3610
 * @widget: a #GtkWidget
3611
 * @x: x coordinate of upper-left corner of rectangle to redraw
3612
 * @y: y coordinate of upper-left corner of rectangle to redraw
3613
 * @width: width of region to draw
3614
 * @height: height of region to draw
3615
 *
3616
 * Invalidates the rectangular area of @widget defined by @x, @y,
3617
 * @width and @height by calling gdk_window_invalidate_rect() on the
3618
 * widget's window and all its child windows. Once the main loop
3619
 * becomes idle (after the current batch of events has been processed,
3620
 * roughly), the window will receive expose events for the union of
3621
 * all regions that have been invalidated.
3622
 *
3623
 * Normally you would only use this function in widget
3624
 * implementations. You might also use it, or
3625
 * gdk_window_invalidate_rect() directly, to schedule a redraw of a
3626
 * #GtkDrawingArea or some portion thereof.
3627
 *
3628
 * Frequently you can just call gdk_window_invalidate_rect() or
3629
 * gdk_window_invalidate_region() instead of this function. Those
3630
 * functions will invalidate only a single window, instead of the
3631
 * widget and all its children.
3632
 *
3633
 * The advantage of adding to the invalidated region compared to
3634
 * simply drawing immediately is efficiency; using an invalid region
3635
 * ensures that you only have to redraw one time.
3636
 **/
3637
void	   
3638
gtk_widget_queue_draw_area (GtkWidget *widget,
3639
			    gint       x,
3640
			    gint       y,
3641
			    gint       width,
3642
 			    gint       height)
3643
{
3644
  GdkRectangle invalid_rect;
3645
  GtkWidget *w;
3646
  
3647
  g_return_if_fail (GTK_IS_WIDGET (widget));
3648
3649
  if (!GTK_WIDGET_REALIZED (widget))
3650
    return;
3651
  
3652
  /* Just return if the widget or one of its ancestors isn't mapped */
3653
  for (w = widget; w != NULL; w = w->parent)
3654
    if (!GTK_WIDGET_MAPPED (w))
3655
      return;
3656
3657
  /* Find the correct widget */
3658
3659
  if (!GTK_WIDGET_NO_WINDOW (widget))
3660
    {
3661
      if (widget->parent)
3662
	{
3663
	  /* Translate widget relative to window-relative */
3664
3665
	  gint wx, wy, wwidth, wheight;
3666
	  
3667
	  gdk_window_get_position (widget->window, &wx, &wy);
3668
	  x -= wx - widget->allocation.x;
3669
	  y -= wy - widget->allocation.y;
3670
	  
3671
	  gdk_drawable_get_size (widget->window, &wwidth, &wheight);
3672
3673
	  if (x + width <= 0 || y + height <= 0 ||
3674
	      x >= wwidth || y >= wheight)
3675
	    return;
3676
	  
3677
	  if (x < 0)
3678
	    {
3679
	      width += x;  x = 0;
3680
	    }
3681
	  if (y < 0)
3682
	    {
3683
	      height += y; y = 0;
3684
	    }
3685
	  if (x + width > wwidth)
3686
	    width = wwidth - x;
3687
	  if (y + height > wheight)
3688
	    height = wheight - y;
3689
	}
3690
    }
3691
3692
  invalid_rect.x = x;
3693
  invalid_rect.y = y;
3694
  invalid_rect.width = width;
3695
  invalid_rect.height = height;
3696
  
3697
  gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
3698
}
3699
3700
static void
3701
widget_add_child_draw_rectangle (GtkWidget    *widget,
3702
				 GdkRectangle *rect)
3703
{
3704
  GdkRectangle child_rect;
3705
  
3706
  if (!GTK_WIDGET_MAPPED (widget) ||
3707
      widget->window != widget->parent->window)
3708
    return;
3709
3710
  gtk_widget_get_draw_rectangle (widget, &child_rect);
3711
  gdk_rectangle_union (rect, &child_rect, rect);
3712
}
3713
3714
static void
3715
gtk_widget_get_draw_rectangle (GtkWidget    *widget,
3716
			       GdkRectangle *rect)
3717
{
3718
  if (GTK_WIDGET_NO_WINDOW (widget))
3719
    {
3720
      GtkBorder *draw_border = NULL;
3721
3722
      *rect = widget->allocation;
3723
3724
      gtk_widget_style_get (widget,
3725
			    "draw-border", &draw_border,
3726
			    NULL);
3727
      if (draw_border)
3728
	{
3729
	  rect->x -= draw_border->left;
3730
	  rect->y -= draw_border->top;
3731
	  rect->width += draw_border->left + draw_border->right;
3732
	  rect->height += draw_border->top + draw_border->bottom;
3733
3734
          gtk_border_free (draw_border);
3735
	}
3736
3737
      if (GTK_IS_CONTAINER (widget))
3738
	gtk_container_forall (GTK_CONTAINER (widget),
3739
			      (GtkCallback)widget_add_child_draw_rectangle,
3740
			      rect);
3741
    }
3742
  else
3743
    {
3744
      rect->x = 0;
3745
      rect->y = 0;
3746
      rect->width = widget->allocation.width;
3747
      rect->height = widget->allocation.height;
3748
    }
3749
}
3750
3751
/**
3752
 * gtk_widget_queue_draw:
3753
 * @widget: a #GtkWidget
3754
 *
3755
 * Equivalent to calling gtk_widget_queue_draw_area() for the
3756
 * entire area of a widget.
3757
 **/
3758
void	   
3759
gtk_widget_queue_draw (GtkWidget *widget)
3760
{
3761
  GdkRectangle rect;
3762
  
3763
  g_return_if_fail (GTK_IS_WIDGET (widget));
3764
3765
  gtk_widget_get_draw_rectangle (widget, &rect);
3766
3767
  gtk_widget_queue_draw_area (widget,
3768
			      rect.x, rect.y,
3769
			      rect.width, rect.height);
3770
}
3771
3772
/* Invalidates the given area (allocation-relative-coordinates)
3773
 * in all of the widget's windows
3774
 */
3775
/**
3776
 * gtk_widget_queue_clear_area:
3777
 * @widget: a #GtkWidget
3778
 * @x: x coordinate of upper-left corner of rectangle to redraw
3779
 * @y: y coordinate of upper-left corner of rectangle to redraw
3780
 * @width: width of region to draw
3781
 * @height: height of region to draw
3782
 * 
3783
 * This function is no longer different from
3784
 * gtk_widget_queue_draw_area(), though it once was. Now it just calls
3785
 * gtk_widget_queue_draw_area(). Originally
3786
 * gtk_widget_queue_clear_area() would force a redraw of the
3787
 * background for %GTK_NO_WINDOW widgets, and
3788
 * gtk_widget_queue_draw_area() would not. Now both functions ensure
3789
 * the background will be redrawn.
3790
 * 
3791
 * Deprecated: 2.2: Use gtk_widget_queue_draw_area() instead.
3792
 **/
3793
void	   
3794
gtk_widget_queue_clear_area (GtkWidget *widget,
3795
			     gint       x,
3796
			     gint       y,
3797
			     gint       width,
3798
			     gint       height)
3799
{
3800
  g_return_if_fail (GTK_IS_WIDGET (widget));
3801
3802
  gtk_widget_queue_draw_area (widget, x, y, width, height);
3803
}
3804
3805
/**
3806
 * gtk_widget_queue_clear:
3807
 * @widget: a #GtkWidget
3808
 * 
3809
 * This function does the same as gtk_widget_queue_draw().
3810
 *
3811
 * Deprecated: 2.2: Use gtk_widget_queue_draw() instead.
3812
 **/
3813
void	   
3814
gtk_widget_queue_clear (GtkWidget *widget)
3815
{
3816
  g_return_if_fail (GTK_IS_WIDGET (widget));
3817
3818
  gtk_widget_queue_draw (widget);
3819
}
3820
3821
/**
3822
 * gtk_widget_queue_resize:
3823
 * @widget: a #GtkWidget
3824
 *
3825
 * This function is only for use in widget implementations.
3826
 * Flags a widget to have its size renegotiated; should
3827
 * be called when a widget for some reason has a new size request.
3828
 * For example, when you change the text in a #GtkLabel, #GtkLabel
3829
 * queues a resize to ensure there's enough space for the new text.
3830
 **/
3831
void
3832
gtk_widget_queue_resize (GtkWidget *widget)
3833
{
3834
  g_return_if_fail (GTK_IS_WIDGET (widget));
3835
3836
  if (GTK_WIDGET_REALIZED (widget))
3837
    gtk_widget_queue_shallow_draw (widget);
3838
      
3839
  _gtk_size_group_queue_resize (widget);
3840
}
3841
3842
/**
3843
 * gtk_widget_queue_resize_no_redraw:
3844
 * @widget: a #GtkWidget
3845
 *
3846
 * This function works like gtk_widget_queue_resize(), 
3847
 * except that the widget is not invalidated.
3848
 *
3849
 * Since: 2.4
3850
 **/
3851
void
3852
gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
3853
{
3854
  g_return_if_fail (GTK_IS_WIDGET (widget));
3855
3856
  _gtk_size_group_queue_resize (widget);
3857
}
3858
3859
/**
3860
 * gtk_widget_draw:
3861
 * @widget: a #GtkWidget
3862
 * @area: area to draw
3863
 *
3864
 * In GTK+ 1.2, this function would immediately render the
3865
 * region @area of a widget, by invoking the virtual draw method of a
3866
 * widget. In GTK+ 2.0, the draw method is gone, and instead
3867
 * gtk_widget_draw() simply invalidates the specified region of the
3868
 * widget, then updates the invalid region of the widget immediately.
3869
 * Usually you don't want to update the region immediately for
3870
 * performance reasons, so in general gtk_widget_queue_draw_area() is
3871
 * a better choice if you want to draw a region of a widget.
3872
 **/
3873
void
3874
gtk_widget_draw (GtkWidget          *widget,
3875
		 const GdkRectangle *area)
3876
{
3877
  g_return_if_fail (GTK_IS_WIDGET (widget));
3878
3879
  if (GTK_WIDGET_DRAWABLE (widget))
3880
    {
3881
      if (area)
3882
        gtk_widget_queue_draw_area (widget,
3883
                                    area->x, area->y,
3884
                                    area->width, area->height);
3885
      else
3886
        gtk_widget_queue_draw (widget);
3887
3888
      gdk_window_process_updates (widget->window, TRUE);
3889
    }
3890
}
3891
3892
/**
3893
 * gtk_widget_size_request:
3894
 * @widget: a #GtkWidget
3895
 * @requisition: a #GtkRequisition to be filled in
3896
 * 
3897
 * This function is typically used when implementing a #GtkContainer
3898
 * subclass.  Obtains the preferred size of a widget. The container
3899
 * uses this information to arrange its child widgets and decide what
3900
 * size allocations to give them with gtk_widget_size_allocate().
3901
 *
3902
 * You can also call this function from an application, with some
3903
 * caveats. Most notably, getting a size request requires the widget
3904
 * to be associated with a screen, because font information may be
3905
 * needed. Multihead-aware applications should keep this in mind.
3906
 *
3907
 * Also remember that the size request is not necessarily the size
3908
 * a widget will actually be allocated.
3909
 *
3910
 * See also gtk_widget_get_child_requisition().
3911
 **/
3912
void
3913
gtk_widget_size_request (GtkWidget	*widget,
3914
			 GtkRequisition *requisition)
3915
{
3916
  g_return_if_fail (GTK_IS_WIDGET (widget));
3917
3918
#ifdef G_ENABLE_DEBUG
3919
  if (requisition == &widget->requisition)
3920
    g_warning ("gtk_widget_size_request() called on child widget with request equal\n to widget->requisition. gtk_widget_set_usize() may not work properly.");
3921
#endif /* G_ENABLE_DEBUG */
3922
3923
  _gtk_size_group_compute_requisition (widget, requisition);
3924
}
3925
3926
/**
3927
 * gtk_widget_get_child_requisition:
3928
 * @widget: a #GtkWidget
3929
 * @requisition: a #GtkRequisition to be filled in
3930
 * 
3931
 * This function is only for use in widget implementations. Obtains
3932
 * @widget->requisition, unless someone has forced a particular
3933
 * geometry on the widget (e.g. with gtk_widget_set_size_request()),
3934
 * in which case it returns that geometry instead of the widget's
3935
 * requisition.
3936
 *
3937
 * This function differs from gtk_widget_size_request() in that
3938
 * it retrieves the last size request value from @widget->requisition,
3939
 * while gtk_widget_size_request() actually calls the "size_request" method
3940
 * on @widget to compute the size request and fill in @widget->requisition,
3941
 * and only then returns @widget->requisition.
3942
 *
3943
 * Because this function does not call the "size_request" method, it
3944
 * can only be used when you know that @widget->requisition is
3945
 * up-to-date, that is, gtk_widget_size_request() has been called
3946
 * since the last time a resize was queued. In general, only container
3947
 * implementations have this information; applications should use
3948
 * gtk_widget_size_request().
3949
 **/
3950
void
3951
gtk_widget_get_child_requisition (GtkWidget	 *widget,
3952
				  GtkRequisition *requisition)
3953
{
3954
  _gtk_size_group_get_child_requisition (widget, requisition);
3955
}
3956
3957
static gboolean
3958
invalidate_predicate (GdkWindow *window,
3959
		      gpointer   data)
3960
{
3961
  gpointer user_data;
3962
3963
  gdk_window_get_user_data (window, &user_data);
3964
3965
  return (user_data == data);
3966
}
3967
3968
/* Invalidate @region in widget->window and all children
3969
 * of widget->window owned by widget. @region is in the
3970
 * same coordinates as widget->allocation and will be
3971
 * modified by this call.
3972
 */
3973
static void
3974
gtk_widget_invalidate_widget_windows (GtkWidget *widget,
3975
				      GdkRegion *region)
3976
{
3977
  if (!GTK_WIDGET_REALIZED (widget))
3978
    return;
3979
  
3980
  if (!GTK_WIDGET_NO_WINDOW (widget) && widget->parent)
3981
    {
3982
      int x, y;
3983
      
3984
      gdk_window_get_position (widget->window, &x, &y);
3985
      gdk_region_offset (region, -x, -y);
3986
    }
3987
3988
  gdk_window_invalidate_maybe_recurse (widget->window, region,
3989
				       invalidate_predicate, widget);
3990
}
3991
3992
/**
3993
 * gtk_widget_queue_shallow_draw:
3994
 * @widget: a #GtkWidget
3995
 *
3996
 * Like gtk_widget_queue_draw(), but only windows owned
3997
 * by @widget are invalidated.
3998
 **/
3999
static void
4000
gtk_widget_queue_shallow_draw (GtkWidget *widget)
4001
{
4002
  GdkRectangle rect;
4003
  GdkRegion *region;
4004
  
4005
  if (!GTK_WIDGET_REALIZED (widget))
4006
    return;
4007
4008
  gtk_widget_get_draw_rectangle (widget, &rect);
4009
4010
  /* get_draw_rectangle() gives us window coordinates, we
4011
   * need to convert to the coordinates that widget->allocation
4012
   * is in.
4013
   */
4014
  if (!GTK_WIDGET_NO_WINDOW (widget) && widget->parent)
4015
    {
4016
      int wx, wy;
4017
      
4018
      gdk_window_get_position (widget->window, &wx, &wy);
4019
      
4020
      rect.x += wx;
4021
      rect.y += wy;
4022
    }
4023
  
4024
  region = gdk_region_rectangle (&rect);
4025
  gtk_widget_invalidate_widget_windows (widget, region);
4026
  gdk_region_destroy (region);
4027
}
4028
4029
/**
4030
 * gtk_widget_size_allocate:
4031
 * @widget: a #GtkWidget
4032
 * @allocation: position and size to be allocated to @widget
4033
 *
4034
 * This function is only used by #GtkContainer subclasses, to assign a size
4035
 * and position to their child widgets. 
4036
 **/
4037
void
4038
gtk_widget_size_allocate (GtkWidget	*widget,
4039
			  GtkAllocation *allocation)
4040
{
4041
  GtkWidgetAuxInfo *aux_info;
4042
  GdkRectangle real_allocation;
4043
  GdkRectangle old_allocation;
4044
  gboolean alloc_needed;
4045
  gboolean size_changed;
4046
  gboolean position_changed;
4047
  
4048
  g_return_if_fail (GTK_IS_WIDGET (widget));
4049
 
4050
#ifdef G_ENABLE_DEBUG
4051
  if (gtk_debug_flags & GTK_DEBUG_GEOMETRY)
4052
    {
4053
      gint depth;
4054
      GtkWidget *parent;
4055
      const gchar *name;
4056
4057
      depth = 0;
4058
      parent = widget;
4059
      while (parent)
4060
	{
4061
	  depth++;
4062
	  parent = gtk_widget_get_parent (parent);
4063
	}
4064
      
4065
      name = g_type_name (G_OBJECT_TYPE (G_OBJECT (widget)));
4066
      g_print ("gtk_widget_size_allocate: %*s%s %d %d\n", 
4067
	       2 * depth, " ", name, 
4068
	       allocation->width, allocation->height);
4069
    }
4070
#endif /* G_ENABLE_DEBUG */
4071
 
4072
  alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
4073
  if (!GTK_WIDGET_REQUEST_NEEDED (widget))      /* Preserve request/allocate ordering */
4074
    GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
4075
4076
  old_allocation = widget->allocation;
4077
  real_allocation = *allocation;
4078
  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
4079
  
4080
  if (aux_info)
4081
    {
4082
      if (aux_info->x_set)
4083
	real_allocation.x = aux_info->x;
4084
      if (aux_info->y_set)
4085
	real_allocation.y = aux_info->y;
4086
    }
4087
4088
  if (real_allocation.width < 0 || real_allocation.height < 0)
4089
    {
4090
      g_warning ("gtk_widget_size_allocate(): attempt to allocate widget with width %d and height %d",
4091
		 real_allocation.width,
4092
		 real_allocation.height);
4093
    }
4094
  
4095
  real_allocation.width = MAX (real_allocation.width, 1);
4096
  real_allocation.height = MAX (real_allocation.height, 1);
4097
4098
  size_changed = (old_allocation.width != real_allocation.width ||
4099
		  old_allocation.height != real_allocation.height);
4100
  position_changed = (old_allocation.x != real_allocation.x ||
4101
		      old_allocation.y != real_allocation.y);
4102
4103
  if (!alloc_needed && !size_changed && !position_changed)
4104
    return;
4105
  
4106
  g_signal_emit (widget, widget_signals[SIZE_ALLOCATE], 0, &real_allocation);
4107
4108
  if (GTK_WIDGET_MAPPED (widget))
4109
    {
4110
      if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
4111
	{
4112
	  /* Invalidate union(old_allaction,widget->allocation) in widget->window
4113
	   */
4114
	  GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
4115
	  gdk_region_union_with_rect (invalidate, &old_allocation);
4116
4117
	  gdk_window_invalidate_region (widget->window, invalidate, FALSE);
4118
	  gdk_region_destroy (invalidate);
4119
	}
4120
      
4121
      if (size_changed)
4122
	{
4123
	  if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
4124
	    {
4125
	      /* Invalidate union(old_allaction,widget->allocation) in widget->window and descendents owned by widget
4126
	       */
4127
	      GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
4128
	      gdk_region_union_with_rect (invalidate, &old_allocation);
4129
4130
	      gtk_widget_invalidate_widget_windows (widget, invalidate);
4131
	      gdk_region_destroy (invalidate);
4132
	    }
4133
	}
4134
    }
4135
4136
  if ((size_changed || position_changed) && widget->parent &&
4137
      GTK_WIDGET_REALIZED (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
4138
    {
4139
      GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
4140
      gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
4141
      gdk_region_destroy (invalidate);
4142
    }
4143
4144
#ifdef MAEMO_CHANGES
4145
  if (GTK_WIDGET_TOPLEVEL (widget))
4146
    _gtk_container_post_size_allocate (GTK_CONTAINER (widget));
4147
#endif
4148
}
4149
4150
/**
4151
 * gtk_widget_common_ancestor:
4152
 * @widget_a: a #GtkWidget
4153
 * @widget_b: a #GtkWidget
4154
 * 
4155
 * Find the common ancestor of @widget_a and @widget_b that
4156
 * is closest to the two widgets.
4157
 * 
4158
 * Return value: the closest common ancestor of @widget_a and
4159
 *   @widget_b or %NULL if @widget_a and @widget_b do not
4160
 *   share a common ancestor.
4161
 **/
4162
static GtkWidget *
4163
gtk_widget_common_ancestor (GtkWidget *widget_a,
4164
			    GtkWidget *widget_b)
4165
{
4166
  GtkWidget *parent_a;
4167
  GtkWidget *parent_b;
4168
  gint depth_a = 0;
4169
  gint depth_b = 0;
4170
4171
  parent_a = widget_a;
4172
  while (parent_a->parent)
4173
    {
4174
      parent_a = parent_a->parent;
4175
      depth_a++;
4176
    }
4177
4178
  parent_b = widget_b;
4179
  while (parent_b->parent)
4180
    {
4181
      parent_b = parent_b->parent;
4182
      depth_b++;
4183
    }
4184
4185
  if (parent_a != parent_b)
4186
    return NULL;
4187
4188
  while (depth_a > depth_b)
4189
    {
4190
      widget_a = widget_a->parent;
4191
      depth_a--;
4192
    }
4193
4194
  while (depth_b > depth_a)
4195
    {
4196
      widget_b = widget_b->parent;
4197
      depth_b--;
4198
    }
4199
4200
  while (widget_a != widget_b)
4201
    {
4202
      widget_a = widget_a->parent;
4203
      widget_b = widget_b->parent;
4204
    }
4205
4206
  return widget_a;
4207
}
4208
4209
/**
4210
 * gtk_widget_translate_coordinates:
4211
 * @src_widget:  a #GtkWidget
4212
 * @dest_widget: a #GtkWidget
4213
 * @src_x: X position relative to @src_widget
4214
 * @src_y: Y position relative to @src_widget
4215
 * @dest_x: location to store X position relative to @dest_widget
4216
 * @dest_y: location to store Y position relative to @dest_widget
4217
 * 
4218
 * Translate coordinates relative to @src_widget's allocation to coordinates
4219
 * relative to @dest_widget's allocations. In order to perform this
4220
 * operation, both widgets must be realized, and must share a common
4221
 * toplevel.
4222
 * 
4223
 * Return value: %FALSE if either widget was not realized, or there
4224
 *   was no common ancestor. In this case, nothing is stored in
4225
 *   *@dest_x and *@dest_y. Otherwise %TRUE.
4226
 **/
4227
gboolean
4228
gtk_widget_translate_coordinates (GtkWidget  *src_widget,
4229
				  GtkWidget  *dest_widget,
4230
				  gint        src_x,
4231
				  gint        src_y,
4232
				  gint       *dest_x,
4233
				  gint       *dest_y)
4234
{
4235
  GtkWidget *ancestor;
4236
  GdkWindow *window;
4237
4238
  g_return_val_if_fail (GTK_IS_WIDGET (src_widget), FALSE);
4239
  g_return_val_if_fail (GTK_IS_WIDGET (dest_widget), FALSE);
4240
4241
  ancestor = gtk_widget_common_ancestor (src_widget, dest_widget);
4242
  if (!ancestor || !GTK_WIDGET_REALIZED (src_widget) || !GTK_WIDGET_REALIZED (dest_widget))
4243
    return FALSE;
4244
4245
  /* Translate from allocation relative to window relative */
4246
  if (!GTK_WIDGET_NO_WINDOW (src_widget) && src_widget->parent)
4247
    {
4248
      gint wx, wy;
4249
      gdk_window_get_position (src_widget->window, &wx, &wy);
4250
4251
      src_x -= wx - src_widget->allocation.x;
4252
      src_y -= wy - src_widget->allocation.y;
4253
    }
4254
  else
4255
    {
4256
      src_x += src_widget->allocation.x;
4257
      src_y += src_widget->allocation.y;
4258
    }
4259
4260
  /* Translate to the common ancestor */
4261
  window = src_widget->window;
4262
  while (window != ancestor->window)
4263
    {
4264
      gint dx, dy;
4265
      
4266
      gdk_window_get_position (window, &dx, &dy);
4267
      
4268
      src_x += dx;
4269
      src_y += dy;
4270
      
4271
      window = gdk_window_get_parent (window);
4272
4273
      if (!window)		/* Handle GtkHandleBox */
4274
	return FALSE;
4275
    }
4276
4277
  /* And back */
4278
  window = dest_widget->window;
4279
  while (window != ancestor->window)
4280
    {
4281
      gint dx, dy;
4282
      
4283
      gdk_window_get_position (window, &dx, &dy);
4284
      
4285
      src_x -= dx;
4286
      src_y -= dy;
4287
      
4288
      window = gdk_window_get_parent (window);
4289
      
4290
      if (!window)		/* Handle GtkHandleBox */
4291
	return FALSE;
4292
    }
4293
4294
  /* Translate from window relative to allocation relative */
4295
  if (!GTK_WIDGET_NO_WINDOW (dest_widget) && dest_widget->parent)
4296
    {
4297
      gint wx, wy;
4298
      gdk_window_get_position (dest_widget->window, &wx, &wy);
4299
4300
      src_x += wx - dest_widget->allocation.x;
4301
      src_y += wy - dest_widget->allocation.y;
4302
    }
4303
  else
4304
    {
4305
      src_x -= dest_widget->allocation.x;
4306
      src_y -= dest_widget->allocation.y;
4307
    }
4308
4309
  if (dest_x)
4310
    *dest_x = src_x;
4311
  if (dest_y)
4312
    *dest_y = src_y;
4313
4314
  return TRUE;
4315
}
4316
4317
static void
4318
gtk_widget_real_size_allocate (GtkWidget     *widget,
4319
			       GtkAllocation *allocation)
4320
{
4321
  widget->allocation = *allocation;
4322
  
4323
  if (GTK_WIDGET_REALIZED (widget) &&
4324
      !GTK_WIDGET_NO_WINDOW (widget))
4325
     {
4326
	gdk_window_move_resize (widget->window,
4327
				allocation->x, allocation->y,
4328
				allocation->width, allocation->height);
4329
     }
4330
}
4331
4332
static gboolean
4333
gtk_widget_real_can_activate_accel (GtkWidget *widget,
4334
                                    guint      signal_id)
4335
{
4336
  /* widgets must be onscreen for accels to take effect */
4337
  return GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_DRAWABLE (widget) && gdk_window_is_viewable (widget->window);
4338
}
4339
4340
/**
4341
 * gtk_widget_can_activate_accel:
4342
 * @widget: a #GtkWidget
4343
 * @signal_id: the ID of a signal installed on @widget
4344
 * 
4345
 * Determines whether an accelerator that activates the signal
4346
 * identified by @signal_id can currently be activated.
4347
 * This is done by emitting the #GtkWidget::can-activate-accel
4348
 * signal on @widget; if the signal isn't overridden by a
4349
 * handler or in a derived widget, then the default check is
4350
 * that the widget must be sensitive, and the widget and all
4351
 * its ancestors mapped.
4352
 *
4353
 * Return value: %TRUE if the accelerator can be activated.
4354
 *
4355
 * Since: 2.4
4356
 **/
4357
gboolean
4358
gtk_widget_can_activate_accel (GtkWidget *widget,
4359
                               guint      signal_id)
4360
{
4361
  gboolean can_activate = FALSE;
4362
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4363
  g_signal_emit (widget, widget_signals[CAN_ACTIVATE_ACCEL], 0, signal_id, &can_activate);
4364
  return can_activate;
4365
}
4366
4367
typedef struct {
4368
  GClosure   closure;
4369
  guint      signal_id;
4370
} AccelClosure;
4371
4372
static void
4373
closure_accel_activate (GClosure     *closure,
4374
			GValue       *return_value,
4375
			guint         n_param_values,
4376
			const GValue *param_values,
4377
			gpointer      invocation_hint,
4378
			gpointer      marshal_data)
4379
{
4380
  AccelClosure *aclosure = (AccelClosure*) closure;
4381
  gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id);
4382
4383
  if (can_activate)
4384
    g_signal_emit (closure->data, aclosure->signal_id, 0);
4385
4386
  /* whether accelerator was handled */
4387
  g_value_set_boolean (return_value, can_activate);
4388
}
4389
4390
static void
4391
closures_destroy (gpointer data)
4392
{
4393
  GSList *slist, *closures = data;
4394
4395
  for (slist = closures; slist; slist = slist->next)
4396
    {
4397
      g_closure_invalidate (slist->data);
4398
      g_closure_unref (slist->data);
4399
    }
4400
  g_slist_free (closures);
4401
}
4402
4403
static GClosure*
4404
widget_new_accel_closure (GtkWidget *widget,
4405
			  guint      signal_id)
4406
{
4407
  AccelClosure *aclosure;
4408
  GClosure *closure = NULL;
4409
  GSList *slist, *closures;
4410
4411
  closures = g_object_steal_qdata (G_OBJECT (widget), quark_accel_closures);
4412
  for (slist = closures; slist; slist = slist->next)
4413
    if (!gtk_accel_group_from_accel_closure (slist->data))
4414
      {
4415
	/* reuse this closure */
4416
	closure = slist->data;
4417
	break;
4418
      }
4419
  if (!closure)
4420
    {
4421
      closure = g_closure_new_object (sizeof (AccelClosure), G_OBJECT (widget));
4422
      closures = g_slist_prepend (closures, g_closure_ref (closure));
4423
      g_closure_sink (closure);
4424
      g_closure_set_marshal (closure, closure_accel_activate);
4425
    }
4426
  g_object_set_qdata_full (G_OBJECT (widget), quark_accel_closures, closures, closures_destroy);
4427
  
4428
  aclosure = (AccelClosure*) closure;
4429
  g_assert (closure->data == widget);
4430
  g_assert (closure->marshal == closure_accel_activate);
4431
  aclosure->signal_id = signal_id;
4432
4433
  return closure;
4434
}
4435
4436
/**
4437
 * gtk_widget_add_accelerator
4438
 * @widget:       widget to install an accelerator on
4439
 * @accel_signal: widget signal to emit on accelerator activation
4440
 * @accel_group:  accel group for this widget, added to its toplevel
4441
 * @accel_key:    GDK keyval of the accelerator
4442
 * @accel_mods:   modifier key combination of the accelerator
4443
 * @accel_flags:  flag accelerators, e.g. %GTK_ACCEL_VISIBLE
4444
 *
4445
 * Installs an accelerator for this @widget in @accel_group that causes
4446
 * @accel_signal to be emitted if the accelerator is activated.
4447
 * The @accel_group needs to be added to the widget's toplevel via
4448
 * gtk_window_add_accel_group(), and the signal must be of type %G_RUN_ACTION.
4449
 * Accelerators added through this function are not user changeable during
4450
 * runtime. If you want to support accelerators that can be changed by the
4451
 * user, use gtk_accel_map_add_entry() and gtk_widget_set_accel_path() or
4452
 * gtk_menu_item_set_accel_path() instead.
4453
 */
4454
void
4455
gtk_widget_add_accelerator (GtkWidget      *widget,
4456
			    const gchar    *accel_signal,
4457
			    GtkAccelGroup  *accel_group,
4458
			    guint           accel_key,
4459
			    GdkModifierType accel_mods,
4460
			    GtkAccelFlags   accel_flags)
4461
{
4462
  GClosure *closure;
4463
  GSignalQuery query;
4464
4465
  g_return_if_fail (GTK_IS_WIDGET (widget));
4466
  g_return_if_fail (accel_signal != NULL);
4467
  g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
4468
4469
  g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query);
4470
  if (!query.signal_id ||
4471
      !(query.signal_flags & G_SIGNAL_ACTION) ||
4472
      query.return_type != G_TYPE_NONE ||
4473
      query.n_params)
4474
    {
4475
      /* hmm, should be elaborate enough */
4476
      g_warning (G_STRLOC ": widget `%s' has no activatable signal \"%s\" without arguments",
4477
		 G_OBJECT_TYPE_NAME (widget), accel_signal);
4478
      return;
4479
    }
4480
4481
  closure = widget_new_accel_closure (widget, query.signal_id);
4482
4483
  g_object_ref (widget);
4484
4485
  /* install the accelerator. since we don't map this onto an accel_path,
4486
   * the accelerator will automatically be locked.
4487
   */
4488
  gtk_accel_group_connect (accel_group,
4489
			   accel_key,
4490
			   accel_mods,
4491
			   accel_flags | GTK_ACCEL_LOCKED,
4492
			   closure);
4493
4494
  g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
4495
4496
  g_object_unref (widget);
4497
}
4498
4499
/**
4500
 * gtk_widget_remove_accelerator:
4501
 * @widget:       widget to install an accelerator on
4502
 * @accel_group:  accel group for this widget
4503
 * @accel_key:    GDK keyval of the accelerator
4504
 * @accel_mods:   modifier key combination of the accelerator
4505
 * @returns:      whether an accelerator was installed and could be removed
4506
 *
4507
 * Removes an accelerator from @widget, previously installed with
4508
 * gtk_widget_add_accelerator().
4509
 */
4510
gboolean
4511
gtk_widget_remove_accelerator (GtkWidget      *widget,
4512
			       GtkAccelGroup  *accel_group,
4513
			       guint           accel_key,
4514
			       GdkModifierType accel_mods)
4515
{
4516
  GtkAccelGroupEntry *ag_entry;
4517
  GList *slist, *clist;
4518
  guint n;
4519
  
4520
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4521
  g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
4522
4523
  ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
4524
  clist = gtk_widget_list_accel_closures (widget);
4525
  for (slist = clist; slist; slist = slist->next)
4526
    {
4527
      guint i;
4528
4529
      for (i = 0; i < n; i++)
4530
	if (slist->data == (gpointer) ag_entry[i].closure)
4531
	  {
4532
	    gboolean is_removed = gtk_accel_group_disconnect (accel_group, slist->data);
4533
4534
	    g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
4535
4536
	    g_list_free (clist);
4537
4538
	    return is_removed;
4539
	  }
4540
    }
4541
  g_list_free (clist);
4542
4543
  g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
4544
	     accel_key, accel_mods, accel_group,
4545
	     G_OBJECT_TYPE_NAME (widget), widget);
4546
4547
  return FALSE;
4548
}
4549
4550
/**
4551
 * gtk_widget_list_accel_closures
4552
 * @widget:  widget to list accelerator closures for
4553
 * @returns: a newly allocated #GList of closures
4554
 *
4555
 * Lists the closures used by @widget for accelerator group connections
4556
 * with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
4557
 * The closures can be used to monitor accelerator changes on @widget,
4558
 * by connecting to the @GtkAccelGroup::accel-changed signal of the 
4559
 * #GtkAccelGroup of a closure which can be found out with 
4560
 * gtk_accel_group_from_accel_closure().
4561
 */
4562
GList*
4563
gtk_widget_list_accel_closures (GtkWidget *widget)
4564
{
4565
  GSList *slist;
4566
  GList *clist = NULL;
4567
4568
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4569
4570
  for (slist = g_object_get_qdata (G_OBJECT (widget), quark_accel_closures); slist; slist = slist->next)
4571
    if (gtk_accel_group_from_accel_closure (slist->data))
4572
      clist = g_list_prepend (clist, slist->data);
4573
  return clist;
4574
}
4575
4576
typedef struct {
4577
  GQuark         path_quark;
4578
  GtkAccelGroup *accel_group;
4579
  GClosure      *closure;
4580
} AccelPath;
4581
4582
static void
4583
destroy_accel_path (gpointer data)
4584
{
4585
  AccelPath *apath = data;
4586
4587
  gtk_accel_group_disconnect (apath->accel_group, apath->closure);
4588
4589
  /* closures_destroy takes care of unrefing the closure */
4590
  g_object_unref (apath->accel_group);
4591
  
4592
  g_slice_free (AccelPath, apath);
4593
}
4594
4595
4596
/**
4597
 * gtk_widget_set_accel_path:
4598
 * @widget: a #GtkWidget
4599
 * @accel_path: path used to look up the accelerator
4600
 * @accel_group: a #GtkAccelGroup.
4601
 * 
4602
 * Given an accelerator group, @accel_group, and an accelerator path,
4603
 * @accel_path, sets up an accelerator in @accel_group so whenever the
4604
 * key binding that is defined for @accel_path is pressed, @widget
4605
 * will be activated.  This removes any accelerators (for any
4606
 * accelerator group) installed by previous calls to
4607
 * gtk_widget_set_accel_path(). Associating accelerators with
4608
 * paths allows them to be modified by the user and the modifications
4609
 * to be saved for future use. (See gtk_accel_map_save().)
4610
 *
4611
 * This function is a low level function that would most likely
4612
 * be used by a menu creation system like #GtkUIManager. If you
4613
 * use #GtkUIManager, setting up accelerator paths will be done
4614
 * automatically.
4615
 *
4616
 * Even when you you aren't using #GtkUIManager, if you only want to
4617
 * set up accelerators on menu items gtk_menu_item_set_accel_path()
4618
 * provides a somewhat more convenient interface.
4619
 * 
4620
 * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
4621
 * pass a static string, you can save some memory by interning it first with 
4622
 * g_intern_static_string().
4623
 **/
4624
void
4625
gtk_widget_set_accel_path (GtkWidget     *widget,
4626
			   const gchar   *accel_path,
4627
			   GtkAccelGroup *accel_group)
4628
{
4629
  AccelPath *apath;
4630
4631
  g_return_if_fail (GTK_IS_WIDGET (widget));
4632
  g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
4633
4634
  if (accel_path)
4635
    {
4636
      g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
4637
      g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
4638
4639
      gtk_accel_map_add_entry (accel_path, 0, 0);
4640
      apath = g_slice_new (AccelPath);
4641
      apath->accel_group = g_object_ref (accel_group);
4642
      apath->path_quark = g_quark_from_string (accel_path);
4643
      apath->closure = widget_new_accel_closure (widget, GTK_WIDGET_GET_CLASS (widget)->activate_signal);
4644
    }
4645
  else
4646
    apath = NULL;
4647
4648
  /* also removes possible old settings */
4649
  g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
4650
4651
  if (apath)
4652
    gtk_accel_group_connect_by_path (apath->accel_group, g_quark_to_string (apath->path_quark), apath->closure);
4653
4654
  g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
4655
}
4656
4657
const gchar*
4658
_gtk_widget_get_accel_path (GtkWidget *widget,
4659
			    gboolean  *locked)
4660
{
4661
  AccelPath *apath;
4662
4663
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
4664
4665
  apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
4666
  if (locked)
4667
    *locked = apath ? apath->accel_group->lock_count > 0 : TRUE;
4668
  return apath ? g_quark_to_string (apath->path_quark) : NULL;
4669
}
4670
4671
gboolean
4672
gtk_widget_mnemonic_activate (GtkWidget *widget,
4673
                              gboolean   group_cycling)
4674
{
4675
  gboolean handled;
4676
  
4677
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
4678
4679
  group_cycling = group_cycling != FALSE;
4680
  if (!GTK_WIDGET_IS_SENSITIVE (widget))
4681
    handled = TRUE;
4682
  else
4683
    g_signal_emit (widget,
4684
		   widget_signals[MNEMONIC_ACTIVATE],
4685
		   0,
4686
		   group_cycling,
4687
		   &handled);
4688
  return handled;
4689
}
4690
4691
static gboolean
4692
gtk_widget_real_mnemonic_activate (GtkWidget *widget,
4693
                                   gboolean   group_cycling)
4694
{
4695
  if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
4696
    gtk_widget_activate (widget);
4697
  else if (GTK_WIDGET_CAN_FOCUS (widget))
4698
    gtk_widget_grab_focus (widget);
4699
  else
4700
    {
4701
      g_warning ("widget `%s' isn't suitable for mnemonic activation",
4702
		 G_OBJECT_TYPE_NAME (widget));
4703
      gtk_widget_error_bell (widget);
4704
    }
4705
  return TRUE;
4706
}
4707
4708
static gboolean
4709
gtk_widget_real_key_press_event (GtkWidget         *widget,
4710
				 GdkEventKey       *event)
4711
{
4712
  return gtk_bindings_activate_event (GTK_OBJECT (widget), event);
4713
}
4714
4715
static gboolean
4716
gtk_widget_real_key_release_event (GtkWidget         *widget,
4717
				   GdkEventKey       *event)
4718
{
4719
  return gtk_bindings_activate_event (GTK_OBJECT (widget), event);
4720
}
4721
4722
static gboolean
4723
gtk_widget_real_focus_in_event (GtkWidget     *widget,
4724
                                GdkEventFocus *event)
4725
{
4726
  gtk_widget_queue_shallow_draw (widget);
4727
4728
  return FALSE;
4729
}
4730
4731
static gboolean
4732
gtk_widget_real_focus_out_event (GtkWidget     *widget,
4733
                                 GdkEventFocus *event)
4734
{
4735
  gtk_widget_queue_shallow_draw (widget);
4736
4737
  return FALSE;
4738
}
4739
4740
#define WIDGET_REALIZED_FOR_EVENT(widget, event) \
4741
     (event->type == GDK_FOCUS_CHANGE || GTK_WIDGET_REALIZED(widget))
4742
4743
/**
4744
 * gtk_widget_event:
4745
 * @widget: a #GtkWidget
4746
 * @event: a #GdkEvent
4747
 * 
4748
 * Rarely-used function. This function is used to emit
4749
 * the event signals on a widget (those signals should never
4750
 * be emitted without using this function to do so).
4751
 * If you want to synthesize an event though, don't use this function;
4752
 * instead, use gtk_main_do_event() so the event will behave as if
4753
 * it were in the event queue. Don't synthesize expose events; instead,
4754
 * use gdk_window_invalidate_rect() to invalidate a region of the
4755
 * window.
4756
 * 
4757
 * Return value: return from the event signal emission (%TRUE if 
4758
 *               the event was handled)
4759
 **/
4760
gboolean
4761
gtk_widget_event (GtkWidget *widget,
4762
		  GdkEvent  *event)
4763
{
4764
  g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
4765
  g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
4766
4767
  if (event->type == GDK_EXPOSE)
4768
    {
4769
      g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
4770
		 "the same effect, call gdk_window_invalidate_rect/region(), "
4771
		 "followed by gdk_window_process_updates().");
4772
      return TRUE;
4773
    }
4774
  
4775
  return gtk_widget_event_internal (widget, event);
4776
}
4777
4778
4779
/**
4780
 * gtk_widget_send_expose:
4781
 * @widget: a #GtkWidget
4782
 * @event: a expose #GdkEvent
4783
 * 
4784
 * Very rarely-used function. This function is used to emit
4785
 * an expose event signals on a widget. This function is not
4786
 * normally used directly. The only time it is used is when
4787
 * propagating an expose event to a child %NO_WINDOW widget, and
4788
 * that is normally done using gtk_container_propagate_expose().
4789
 *
4790
 * If you want to force an area of a window to be redrawn, 
4791
 * use gdk_window_invalidate_rect() or gdk_window_invalidate_region().
4792
 * To cause the redraw to be done immediately, follow that call
4793
 * with a call to gdk_window_process_updates().
4794
 * 
4795
 * Return value: return from the event signal emission (%TRUE if 
4796
 *               the event was handled)
4797
 **/
4798
gint
4799
gtk_widget_send_expose (GtkWidget *widget,
4800
			GdkEvent  *event)
4801
{
4802
  g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
4803
  g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), TRUE);
4804
  g_return_val_if_fail (event != NULL, TRUE);
4805
  g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
4806
4807
  return gtk_widget_event_internal (widget, event);
4808
}
4809
4810
static gboolean
4811
event_window_is_still_viewable (GdkEvent *event)
4812
{
4813
  /* Some programs, such as gnome-theme-manager, fake widgets
4814
   * into exposing onto a pixmap by sending expose events with
4815
   * event->window pointing to a pixmap
4816
   */
4817
  if (GDK_IS_PIXMAP (event->any.window))
4818
    return event->type == GDK_EXPOSE;
4819
  
4820
  /* Check that we think the event's window is viewable before
4821
   * delivering the event, to prevent suprises. We do this here
4822
   * at the last moment, since the event may have been queued
4823
   * up behind other events, held over a recursive main loop, etc.
4824
   */
4825
  switch (event->type)
4826
    {
4827
    case GDK_EXPOSE:
4828
    case GDK_MOTION_NOTIFY:
4829
    case GDK_BUTTON_PRESS:
4830
    case GDK_2BUTTON_PRESS:
4831
    case GDK_3BUTTON_PRESS:
4832
    case GDK_KEY_PRESS:
4833
    case GDK_ENTER_NOTIFY:
4834
    case GDK_PROXIMITY_IN:
4835
    case GDK_SCROLL:
4836
      return event->any.window && gdk_window_is_viewable (event->any.window);
4837
4838
#if 0
4839
    /* The following events are the second half of paired events;
4840
     * we always deliver them to deal with widgets that clean up
4841
     * on the second half.
4842
     */
4843
    case GDK_BUTTON_RELEASE:
4844
    case GDK_KEY_RELEASE:
4845
    case GDK_LEAVE_NOTIFY:
4846
    case GDK_PROXIMITY_OUT:
4847
#endif      
4848
      
4849
    default:
4850
      /* Remaining events would make sense on an not-viewable window,
4851
       * or don't have an associated window.
4852
       */
4853
      return TRUE;
4854
    }
4855
}
4856
4857
static gint
4858
gtk_widget_event_internal (GtkWidget *widget,
4859
			   GdkEvent  *event)
4860
{
4861
  gboolean return_val = FALSE;
4862
4863
  /* We check only once for is-still-visible; if someone
4864
   * hides the window in on of the signals on the widget,
4865
   * they are responsible for returning TRUE to terminate
4866
   * handling.
4867
   */
4868
  if (!event_window_is_still_viewable (event))
4869
    return TRUE;
4870
4871
  g_object_ref (widget);
4872
4873
  g_signal_emit (widget, widget_signals[EVENT], 0, event, &return_val);
4874
  return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
4875
  if (!return_val)
4876
    {
4877
      gint signal_num;
4878
4879
      switch (event->type)
4880
	{
4881
	case GDK_NOTHING:
4882
	  signal_num = -1;
4883
	  break;
4884
	case GDK_BUTTON_PRESS:
4885
	case GDK_2BUTTON_PRESS:
4886
	case GDK_3BUTTON_PRESS:
4887
	  signal_num = BUTTON_PRESS_EVENT;
4888
	  break;
4889
	case GDK_SCROLL:
4890
	  signal_num = SCROLL_EVENT;
4891
	  break;
4892
	case GDK_BUTTON_RELEASE:
4893
	  signal_num = BUTTON_RELEASE_EVENT;
4894
	  break;
4895
	case GDK_MOTION_NOTIFY:
4896
	  signal_num = MOTION_NOTIFY_EVENT;
4897
	  break;
4898
	case GDK_DELETE:
4899
	  signal_num = DELETE_EVENT;
4900
	  break;
4901
	case GDK_DESTROY:
4902
	  signal_num = DESTROY_EVENT;
4903
	  _gtk_tooltip_hide (widget);
4904
	  break;
4905
	case GDK_KEY_PRESS:
4906
	  signal_num = KEY_PRESS_EVENT;
4907
	  break;
4908
	case GDK_KEY_RELEASE:
4909
	  signal_num = KEY_RELEASE_EVENT;
4910
	  break;
4911
	case GDK_ENTER_NOTIFY:
4912
	  signal_num = ENTER_NOTIFY_EVENT;
4913
	  break;
4914
	case GDK_LEAVE_NOTIFY:
4915
	  signal_num = LEAVE_NOTIFY_EVENT;
4916
	  break;
4917
	case GDK_FOCUS_CHANGE:
4918
	  signal_num = event->focus_change.in ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
4919
	  if (event->focus_change.in)
4920
	    _gtk_tooltip_focus_in (widget);
4921
	  else
4922
	    _gtk_tooltip_focus_out (widget);
4923
	  break;
4924
	case GDK_CONFIGURE:
4925
	  signal_num = CONFIGURE_EVENT;
4926
	  break;
4927
	case GDK_MAP:
4928
	  signal_num = MAP_EVENT;
4929
	  break;
4930
	case GDK_UNMAP:
4931
	  signal_num = UNMAP_EVENT;
4932
	  break;
4933
	case GDK_WINDOW_STATE:
4934
	  signal_num = WINDOW_STATE_EVENT;
4935
	  break;
4936
	case GDK_PROPERTY_NOTIFY:
4937
	  signal_num = PROPERTY_NOTIFY_EVENT;
4938
	  break;
4939
	case GDK_SELECTION_CLEAR:
4940
	  signal_num = SELECTION_CLEAR_EVENT;
4941
	  break;
4942
	case GDK_SELECTION_REQUEST:
4943
	  signal_num = SELECTION_REQUEST_EVENT;
4944
	  break;
4945
	case GDK_SELECTION_NOTIFY:
4946
	  signal_num = SELECTION_NOTIFY_EVENT;
4947
	  break;
4948
	case GDK_PROXIMITY_IN:
4949
	  signal_num = PROXIMITY_IN_EVENT;
4950
	  break;
4951
	case GDK_PROXIMITY_OUT:
4952
	  signal_num = PROXIMITY_OUT_EVENT;
4953
	  break;
4954
	case GDK_NO_EXPOSE:
4955
	  signal_num = NO_EXPOSE_EVENT;
4956
	  break;
4957
	case GDK_CLIENT_EVENT:
4958
	  signal_num = CLIENT_EVENT;
4959
	  break;
4960
	case GDK_EXPOSE:
4961
	  signal_num = EXPOSE_EVENT;
4962
	  break;
4963
	case GDK_VISIBILITY_NOTIFY:
4964
	  signal_num = VISIBILITY_NOTIFY_EVENT;
4965
	  break;
4966
	case GDK_GRAB_BROKEN:
4967
	  signal_num = GRAB_BROKEN;
4968
	  break;
4969
	case GDK_DAMAGE:
4970
	  signal_num = DAMAGE_EVENT;
4971
	  break;
4972
	default:
4973
	  g_warning ("gtk_widget_event(): unhandled event type: %d", event->type);
4974
	  signal_num = -1;
4975
	  break;
4976
	}
4977
      if (signal_num != -1)
4978
	g_signal_emit (widget, widget_signals[signal_num], 0, event, &return_val);
4979
    }
4980
  if (WIDGET_REALIZED_FOR_EVENT (widget, event))
4981
    g_signal_emit (widget, widget_signals[EVENT_AFTER], 0, event);
4982
  else
4983
    return_val = TRUE;
4984
4985
  g_object_unref (widget);
4986
4987
  return return_val;
4988
}
4989
4990
/**
4991
 * gtk_widget_activate:
4992
 * @widget: a #GtkWidget that's activatable
4993
 * 
4994
 * For widgets that can be "activated" (buttons, menu items, etc.)
4995
 * this function activates them. Activation is what happens when you
4996
 * press Enter on a widget during key navigation. If @widget isn't 
4997
 * activatable, the function returns %FALSE.
4998
 * 
4999
 * Return value: %TRUE if the widget was activatable
5000
 **/
5001
gboolean
5002
gtk_widget_activate (GtkWidget *widget)
5003
{
5004
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
5005
  
5006
  if (WIDGET_CLASS (widget)->activate_signal)
5007
    {
5008
      /* FIXME: we should eventually check the signals signature here */
5009
      g_signal_emit (widget, WIDGET_CLASS (widget)->activate_signal, 0);
5010
5011
      return TRUE;
5012
    }
5013
  else
5014
    return FALSE;
5015
}
5016
5017
/**
5018
 * gtk_widget_set_scroll_adjustments:
5019
 * @widget: a #GtkWidget
5020
 * @hadjustment: an adjustment for horizontal scrolling, or %NULL
5021
 * @vadjustment: an adjustment for vertical scrolling, or %NULL
5022
 *
5023
 * For widgets that support scrolling, sets the scroll adjustments and
5024
 * returns %TRUE.  For widgets that don't support scrolling, does
5025
 * nothing and returns %FALSE. Widgets that don't support scrolling
5026
 * can be scrolled by placing them in a #GtkViewport, which does
5027
 * support scrolling.
5028
 * 
5029
 * Return value: %TRUE if the widget supports scrolling
5030
 **/
5031
gboolean
5032
gtk_widget_set_scroll_adjustments (GtkWidget     *widget,
5033
				   GtkAdjustment *hadjustment,
5034
				   GtkAdjustment *vadjustment)
5035
{
5036
  guint signal_id;
5037
  GSignalQuery query;
5038
5039
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
5040
5041
  if (hadjustment)
5042
    g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), FALSE);
5043
  if (vadjustment)
5044
    g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), FALSE);
5045
5046
  signal_id = WIDGET_CLASS (widget)->set_scroll_adjustments_signal;
5047
  if (!signal_id)
5048
    return FALSE;
5049
5050
  g_signal_query (signal_id, &query);
5051
  if (!query.signal_id ||
5052
      !g_type_is_a (query.itype, GTK_TYPE_WIDGET) ||
5053
      query.return_type != G_TYPE_NONE ||
5054
      query.n_params != 2 ||
5055
      query.param_types[0] != GTK_TYPE_ADJUSTMENT ||
5056
      query.param_types[1] != GTK_TYPE_ADJUSTMENT)
5057
    {
5058
      g_warning (G_STRLOC ": signal \"%s::%s\" has wrong signature",
5059
		 G_OBJECT_TYPE_NAME (widget), query.signal_name);
5060
      return FALSE;
5061
    }
5062
      
5063
  g_signal_emit (widget, signal_id, 0, hadjustment, vadjustment);
5064
  return TRUE;
5065
}
5066
5067
static void
5068
gtk_widget_reparent_subwindows (GtkWidget *widget,
5069
				GdkWindow *new_window)
5070
{
5071
  if (GTK_WIDGET_NO_WINDOW (widget))
5072
    {
5073
      GList *children = gdk_window_get_children (widget->window);
5074
      GList *tmp_list;
5075
5076
      for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
5077
	{
5078
	  GdkWindow *window = tmp_list->data;
5079
	  gpointer child;
5080
5081
	  gdk_window_get_user_data (window, &child);
5082
	  while (child && child != widget)
5083
	    child = ((GtkWidget*) child)->parent;
5084
5085
	  if (child)
5086
	    gdk_window_reparent (window, new_window, 0, 0);
5087
	}
5088
5089
      g_list_free (children);
5090
    }
5091
  else
5092
   {
5093
     GdkWindow *parent;
5094
     GList *tmp_list, *children;
5095
5096
     parent = gdk_window_get_parent (widget->window);
5097
5098
     if (parent == NULL)
5099
       gdk_window_reparent (widget->window, new_window, 0, 0);
5100
     else
5101
       {
5102
	 children = gdk_window_get_children (parent);
5103
	 
5104
	 for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
5105
	   {
5106
	     GdkWindow *window = tmp_list->data;
5107
	     gpointer child;
5108
5109
	     gdk_window_get_user_data (window, &child);
5110
5111
	     if (child == widget)
5112
	       gdk_window_reparent (window, new_window, 0, 0);
5113
	   }
5114
	 
5115
	 g_list_free (children);
5116
       }
5117
   }
5118
}
5119
5120
static void
5121
gtk_widget_reparent_fixup_child (GtkWidget *widget,
5122
				 gpointer   client_data)
5123
{
5124
  g_assert (client_data != NULL);
5125
  
5126
  if (GTK_WIDGET_NO_WINDOW (widget))
5127
    {
5128
      if (widget->window)
5129
	g_object_unref (widget->window);
5130
      widget->window = (GdkWindow*) client_data;
5131
      if (widget->window)
5132
	g_object_ref (widget->window);
5133
5134
      if (GTK_IS_CONTAINER (widget))
5135
        gtk_container_forall (GTK_CONTAINER (widget),
5136
                              gtk_widget_reparent_fixup_child,
5137
                              client_data);
5138
    }
5139
}
5140
5141
/**
5142
 * gtk_widget_reparent:
5143
 * @widget: a #GtkWidget
5144
 * @new_parent: a #GtkContainer to move the widget into
5145
 *
5146
 * Moves a widget from one #GtkContainer to another, handling reference
5147
 * count issues to avoid destroying the widget.
5148
 **/
5149
void
5150
gtk_widget_reparent (GtkWidget *widget,
5151
		     GtkWidget *new_parent)
5152
{
5153
  g_return_if_fail (GTK_IS_WIDGET (widget));
5154
  g_return_if_fail (GTK_IS_CONTAINER (new_parent));
5155
  g_return_if_fail (widget->parent != NULL);
5156
  
5157
  if (widget->parent != new_parent)
5158
    {
5159
      /* First try to see if we can get away without unrealizing
5160
       * the widget as we reparent it. if so we set a flag so
5161
       * that gtk_widget_unparent doesn't unrealize widget
5162
       */
5163
      if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
5164
	GTK_PRIVATE_SET_FLAG (widget, GTK_IN_REPARENT);
5165
      
5166
      g_object_ref (widget);
5167
      gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
5168
      gtk_container_add (GTK_CONTAINER (new_parent), widget);
5169
      g_object_unref (widget);
5170
      
5171
      if (GTK_WIDGET_IN_REPARENT (widget))
5172
	{
5173
	  GTK_PRIVATE_UNSET_FLAG (widget, GTK_IN_REPARENT);
5174
5175
	  gtk_widget_reparent_subwindows (widget, gtk_widget_get_parent_window (widget));
5176
	  gtk_widget_reparent_fixup_child (widget,
5177
					   gtk_widget_get_parent_window (widget));
5178
	}
5179
5180
      g_object_notify (G_OBJECT (widget), "parent");
5181
    }
5182
}
5183
5184
/**
5185
 * gtk_widget_intersect:
5186
 * @widget: a #GtkWidget
5187
 * @area: a rectangle
5188
 * @intersection: rectangle to store intersection of @widget and @area
5189
 * 
5190
 * Computes the intersection of a @widget's area and @area, storing
5191
 * the intersection in @intersection, and returns %TRUE if there was
5192
 * an intersection.  @intersection may be %NULL if you're only
5193
 * interested in whether there was an intersection.
5194
 * 
5195
 * Return value: %TRUE if there was an intersection
5196
 **/
5197
gboolean
5198
gtk_widget_intersect (GtkWidget	         *widget,
5199
		      const GdkRectangle *area,
5200
		      GdkRectangle       *intersection)
5201
{
5202
  GdkRectangle *dest;
5203
  GdkRectangle tmp;
5204
  gint return_val;
5205
  
5206
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
5207
  g_return_val_if_fail (area != NULL, FALSE);
5208
  
5209
  if (intersection)
5210
    dest = intersection;
5211
  else
5212
    dest = &tmp;
5213
  
5214
  return_val = gdk_rectangle_intersect (&widget->allocation, area, dest);
5215
  
5216
  if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
5217
    {
5218
      intersection->x -= widget->allocation.x;
5219
      intersection->y -= widget->allocation.y;
5220
    }
5221
  
5222
  return return_val;
5223
}
5224
5225
/**
5226
 * gtk_widget_region_intersect:
5227
 * @widget: a #GtkWidget
5228
 * @region: a #GdkRegion, in the same coordinate system as 
5229
 *          @widget->allocation. That is, relative to @widget->window
5230
 *          for %NO_WINDOW widgets; relative to the parent window
5231
 *          of @widget->window for widgets with their own window.
5232
 * @returns: A newly allocated region holding the intersection of @widget
5233
 *           and @region. The coordinates of the return value are
5234
 *           relative to @widget->window for %NO_WINDOW widgets, and
5235
 *           relative to the parent window of @widget->window for
5236
 *           widgets with their own window.
5237
 * 
5238
 * Computes the intersection of a @widget's area and @region, returning
5239
 * the intersection. The result may be empty, use gdk_region_empty() to
5240
 * check.
5241
 **/
5242
GdkRegion *
5243
gtk_widget_region_intersect (GtkWidget       *widget,
5244
			     const GdkRegion *region)
5245
{
5246
  GdkRectangle rect;
5247
  GdkRegion *dest;
5248
  
5249
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5250
  g_return_val_if_fail (region != NULL, NULL);
5251
5252
  gtk_widget_get_draw_rectangle (widget, &rect);
5253
  
5254
  dest = gdk_region_rectangle (&rect);
5255
 
5256
  gdk_region_intersect (dest, region);
5257
5258
  return dest;
5259
}
5260
5261
/**
5262
 * _gtk_widget_grab_notify:
5263
 * @widget: a #GtkWidget
5264
 * @was_grabbed: whether a grab is now in effect
5265
 * 
5266
 * Emits the #GtkWidget::grab-notify signal on @widget.
5267
 * 
5268
 * Since: 2.6
5269
 **/
5270
void
5271
_gtk_widget_grab_notify (GtkWidget *widget,
5272
			 gboolean   was_grabbed)
5273
{
5274
  g_signal_emit (widget, widget_signals[GRAB_NOTIFY], 0, was_grabbed);
5275
}
5276
5277
/**
5278
 * gtk_widget_grab_focus:
5279
 * @widget: a #GtkWidget
5280
 * 
5281
 * Causes @widget to have the keyboard focus for the #GtkWindow it's
5282
 * inside. @widget must be a focusable widget, such as a #GtkEntry;
5283
 * something like #GtkFrame won't work. (More precisely, it must have the
5284
 * %GTK_CAN_FOCUS flag set.)
5285
 **/
5286
void
5287
gtk_widget_grab_focus (GtkWidget *widget)
5288
{
5289
  g_return_if_fail (GTK_IS_WIDGET (widget));
5290
5291
  if (!GTK_WIDGET_IS_SENSITIVE (widget))
5292
    return;
5293
  
5294
  g_object_ref (widget);
5295
  g_signal_emit (widget, widget_signals[GRAB_FOCUS], 0);
5296
  g_object_notify (G_OBJECT (widget), "has-focus");
5297
  g_object_unref (widget);
5298
}
5299
5300
static void
5301
reset_focus_recurse (GtkWidget *widget,
5302
		     gpointer   data)
5303
{
5304
  if (GTK_IS_CONTAINER (widget))
5305
    {
5306
      GtkContainer *container;
5307
5308
      container = GTK_CONTAINER (widget);
5309
      gtk_container_set_focus_child (container, NULL);
5310
5311
      gtk_container_foreach (container,
5312
			     reset_focus_recurse,
5313
			     NULL);
5314
    }
5315
}
5316
5317
static void
5318
gtk_widget_real_grab_focus (GtkWidget *focus_widget)
5319
{
5320
  if (GTK_WIDGET_CAN_FOCUS (focus_widget))
5321
    {
5322
      GtkWidget *toplevel;
5323
      GtkWidget *widget;
5324
      
5325
      /* clear the current focus setting, break if the current widget
5326
       * is the focus widget's parent, since containers above that will
5327
       * be set by the next loop.
5328
       */
5329
      toplevel = gtk_widget_get_toplevel (focus_widget);
5330
      if (GTK_WIDGET_TOPLEVEL (toplevel))
5331
	{
5332
	  widget = GTK_WINDOW (toplevel)->focus_widget;
5333
	  
5334
	  if (widget == focus_widget)
5335
	    {
5336
	      /* We call _gtk_window_internal_set_focus() here so that the
5337
	       * toplevel window can request the focus if necessary.
5338
	       * This is needed when the toplevel is a GtkPlug
5339
	       */
5340
	      if (!GTK_WIDGET_HAS_FOCUS (widget))
5341
		_gtk_window_internal_set_focus (GTK_WINDOW (toplevel), focus_widget);
5342
5343
	      return;
5344
	    }
5345
	  
5346
	  if (widget)
5347
	    {
5348
	      while (widget->parent && widget->parent != focus_widget->parent)
5349
		{
5350
		  widget = widget->parent;
5351
		  gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
5352
		}
5353
	    }
5354
	}
5355
      else if (toplevel != focus_widget)
5356
	{
5357
	  /* gtk_widget_grab_focus() operates on a tree without window...
5358
	   * actually, this is very questionable behaviour.
5359
	   */
5360
	  
5361
	  gtk_container_foreach (GTK_CONTAINER (toplevel),
5362
				 reset_focus_recurse,
5363
				 NULL);
5364
	}
5365
5366
      /* now propagate the new focus up the widget tree and finally
5367
       * set it on the window
5368
       */
5369
      widget = focus_widget;
5370
      while (widget->parent)
5371
	{
5372
	  gtk_container_set_focus_child (GTK_CONTAINER (widget->parent), widget);
5373
	  widget = widget->parent;
5374
	}
5375
      if (GTK_IS_WINDOW (widget))
5376
	_gtk_window_internal_set_focus (GTK_WINDOW (widget), focus_widget);
5377
    }
5378
}
5379
5380
static gboolean
5381
gtk_widget_real_query_tooltip (GtkWidget  *widget,
5382
			       gint        x,
5383
			       gint        y,
5384
			       gboolean    keyboard_tip,
5385
			       GtkTooltip *tooltip)
5386
{
5387
  gchar *tooltip_markup;
5388
  gboolean has_tooltip;
5389
5390
  tooltip_markup = g_object_get_qdata (G_OBJECT (widget), quark_tooltip_markup);
5391
  has_tooltip = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (widget), quark_has_tooltip));
5392
5393
  if (has_tooltip && tooltip_markup)
5394
    {
5395
      gtk_tooltip_set_markup (tooltip, tooltip_markup);
5396
      return TRUE;
5397
    }
5398
5399
  return FALSE;
5400
}
5401
5402
static gboolean
5403
gtk_widget_real_show_help (GtkWidget        *widget,
5404
                           GtkWidgetHelpType help_type)
5405
{
5406
  if (help_type == GTK_WIDGET_HELP_TOOLTIP)
5407
    {
5408
      _gtk_tooltip_toggle_keyboard_mode (widget);
5409
5410
      return TRUE;
5411
    }
5412
  else
5413
    return FALSE;
5414
}
5415
5416
static gboolean
5417
gtk_widget_real_focus (GtkWidget         *widget,
5418
                       GtkDirectionType   direction)
5419
{
5420
  if (!GTK_WIDGET_CAN_FOCUS (widget))
5421
    return FALSE;
5422
  
5423
  if (!gtk_widget_is_focus (widget))
5424
    {
5425
      gtk_widget_grab_focus (widget);
5426
      return TRUE;
5427
    }
5428
  else
5429
    return FALSE;
5430
}
5431
5432
static void
5433
gtk_widget_real_move_focus (GtkWidget         *widget,
5434
                            GtkDirectionType   direction)
5435
{
5436
  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
5437
5438
  if (GTK_IS_WINDOW (toplevel) &&
5439
      GTK_WINDOW_GET_CLASS (toplevel)->move_focus)
5440
    {
5441
      GTK_WINDOW_GET_CLASS (toplevel)->move_focus (GTK_WINDOW (toplevel),
5442
                                                   direction);
5443
    }
5444
}
5445
5446
static gboolean
5447
gtk_widget_real_keynav_failed (GtkWidget        *widget,
5448
                               GtkDirectionType  direction)
5449
{
5450
  gboolean cursor_only;
5451
5452
  switch (direction)
5453
    {
5454
    case GTK_DIR_TAB_FORWARD:
5455
    case GTK_DIR_TAB_BACKWARD:
5456
      return FALSE;
5457
5458
    case GTK_DIR_UP:
5459
    case GTK_DIR_DOWN:
5460
    case GTK_DIR_LEFT:
5461
    case GTK_DIR_RIGHT:
5462
      g_object_get (gtk_widget_get_settings (widget),
5463
                    "gtk-keynav-cursor-only", &cursor_only,
5464
                    NULL);
5465
      if (cursor_only)
5466
        return FALSE;
5467
      break;
5468
    }
5469
5470
  gtk_widget_error_bell (widget);
5471
5472
  return TRUE;
5473
}
5474
5475
/**
5476
 * gtk_widget_is_focus:
5477
 * @widget: a #GtkWidget
5478
 * 
5479
 * Determines if the widget is the focus widget within its
5480
 * toplevel. (This does not mean that the %HAS_FOCUS flag is
5481
 * necessarily set; %HAS_FOCUS will only be set if the
5482
 * toplevel widget additionally has the global input focus.)
5483
 * 
5484
 * Return value: %TRUE if the widget is the focus widget.
5485
 **/
5486
gboolean
5487
gtk_widget_is_focus (GtkWidget *widget)
5488
{
5489
  GtkWidget *toplevel;
5490
5491
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
5492
5493
  toplevel = gtk_widget_get_toplevel (widget);
5494
  
5495
  if (GTK_IS_WINDOW (toplevel))
5496
    return widget == GTK_WINDOW (toplevel)->focus_widget;
5497
  else
5498
    return FALSE;
5499
}
5500
5501
/**
5502
 * gtk_widget_grab_default:
5503
 * @widget: a #GtkWidget
5504
 *
5505
 * Causes @widget to become the default widget. @widget must have the
5506
 * %GTK_CAN_DEFAULT flag set; typically you have to set this flag
5507
 * yourself by calling <literal>GTK_WIDGET_SET_FLAGS (@widget,
5508
 * GTK_CAN_DEFAULT)</literal>. The default widget is activated when 
5509
 * the user presses Enter in a window. Default widgets must be 
5510
 * activatable, that is, gtk_widget_activate() should affect them.
5511
 **/
5512
void
5513
gtk_widget_grab_default (GtkWidget *widget)
5514
{
5515
  GtkWidget *window;
5516
  
5517
  g_return_if_fail (GTK_IS_WIDGET (widget));
5518
  g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
5519
  
5520
  window = gtk_widget_get_toplevel (widget);
5521
  
5522
  if (window && GTK_WIDGET_TOPLEVEL (window))
5523
    gtk_window_set_default (GTK_WINDOW (window), widget);
5524
  else
5525
    g_warning (G_STRLOC ": widget not within a GtkWindow");
5526
}
5527
5528
/**
5529
 * gtk_widget_set_name:
5530
 * @widget: a #GtkWidget
5531
 * @name: name for the widget
5532
 *
5533
 * Widgets can be named, which allows you to refer to them from a
5534
 * gtkrc file. You can apply a style to widgets with a particular name
5535
 * in the gtkrc file. See the documentation for gtkrc files (on the
5536
 * same page as the docs for #GtkRcStyle).
5537
 * 
5538
 * Note that widget names are separated by periods in paths (see 
5539
 * gtk_widget_path()), so names with embedded periods may cause confusion.
5540
 **/
5541
void
5542
gtk_widget_set_name (GtkWidget	 *widget,
5543
		     const gchar *name)
5544
{
5545
  gchar *new_name;
5546
  
5547
  g_return_if_fail (GTK_IS_WIDGET (widget));
5548
5549
  new_name = g_strdup (name);
5550
  g_free (widget->name);
5551
  widget->name = new_name;
5552
5553
  if (GTK_WIDGET_RC_STYLE (widget))
5554
    gtk_widget_reset_rc_style (widget);
5555
5556
  g_object_notify (G_OBJECT (widget), "name");
5557
}
5558
5559
/**
5560
 * gtk_widget_get_name:
5561
 * @widget: a #GtkWidget
5562
 * 
5563
 * Retrieves the name of a widget. See gtk_widget_set_name() for the
5564
 * significance of widget names.
5565
 * 
5566
 * Return value: name of the widget. This string is owned by GTK+ and
5567
 * should not be modified or freed
5568
 **/
5569
G_CONST_RETURN gchar*
5570
gtk_widget_get_name (GtkWidget *widget)
5571
{
5572
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5573
  
5574
  if (widget->name)
5575
    return widget->name;
5576
  return g_type_name (GTK_WIDGET_TYPE (widget));
5577
}
5578
5579
/**
5580
 * gtk_widget_set_state:
5581
 * @widget: a #GtkWidget
5582
 * @state: new state for @widget
5583
 *
5584
 * This function is for use in widget implementations. Sets the state
5585
 * of a widget (insensitive, prelighted, etc.) Usually you should set
5586
 * the state using wrapper functions such as gtk_widget_set_sensitive().
5587
 **/
5588
void
5589
gtk_widget_set_state (GtkWidget           *widget,
5590
		      GtkStateType         state)
5591
{
5592
  g_return_if_fail (GTK_IS_WIDGET (widget));
5593
5594
  if (state == GTK_WIDGET_STATE (widget))
5595
    return;
5596
5597
  if (state == GTK_STATE_INSENSITIVE)
5598
    gtk_widget_set_sensitive (widget, FALSE);
5599
  else
5600
    {
5601
      GtkStateData data;
5602
5603
      data.state = state;
5604
      data.state_restoration = FALSE;
5605
      data.use_forall = FALSE;
5606
      if (widget->parent)
5607
	data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
5608
      else
5609
	data.parent_sensitive = TRUE;
5610
5611
      gtk_widget_propagate_state (widget, &data);
5612
  
5613
      if (GTK_WIDGET_DRAWABLE (widget))
5614
	gtk_widget_queue_draw (widget);
5615
    }
5616
}
5617
5618
5619
/**
5620
 * gtk_widget_set_app_paintable:
5621
 * @widget: a #GtkWidget
5622
 * @app_paintable: %TRUE if the application will paint on the widget
5623
 *
5624
 * Sets whether the application intends to draw on the widget in
5625
 * an #GtkWidget::expose-event handler. 
5626
 *
5627
 * This is a hint to the widget and does not affect the behavior of 
5628
 * the GTK+ core; many widgets ignore this flag entirely. For widgets 
5629
 * that do pay attention to the flag, such as #GtkEventBox and #GtkWindow, 
5630
 * the effect is to suppress default themed drawing of the widget's 
5631
 * background. (Children of the widget will still be drawn.) The application 
5632
 * is then entirely responsible for drawing the widget background.
5633
 *
5634
 * Note that the background is still drawn when the widget is mapped.
5635
 * If this is not suitable (e.g. because you want to make a transparent
5636
 * window using an RGBA visual), you can work around this by doing:
5637
 * |[
5638
 *  gtk_widget_realize (window);
5639
 *  gdk_window_set_back_pixmap (window->window, NULL, FALSE);
5640
 *  gtk_widget_show (window);
5641
 * ]|
5642
 **/
5643
void
5644
gtk_widget_set_app_paintable (GtkWidget *widget,
5645
			      gboolean   app_paintable)
5646
{
5647
  g_return_if_fail (GTK_IS_WIDGET (widget));
5648
5649
  app_paintable = (app_paintable != FALSE);
5650
5651
  if (GTK_WIDGET_APP_PAINTABLE (widget) != app_paintable)
5652
    {
5653
      if (app_paintable)
5654
	GTK_WIDGET_SET_FLAGS (widget, GTK_APP_PAINTABLE);
5655
      else
5656
	GTK_WIDGET_UNSET_FLAGS (widget, GTK_APP_PAINTABLE);
5657
5658
      if (GTK_WIDGET_DRAWABLE (widget))
5659
	gtk_widget_queue_draw (widget);
5660
5661
      g_object_notify (G_OBJECT (widget), "app-paintable");
5662
    }
5663
}
5664
5665
/**
5666
 * gtk_widget_set_double_buffered:
5667
 * @widget: a #GtkWidget
5668
 * @double_buffered: %TRUE to double-buffer a widget
5669
 *
5670
 * Widgets are double buffered by default; you can use this function
5671
 * to turn off the buffering. "Double buffered" simply means that
5672
 * gdk_window_begin_paint_region() and gdk_window_end_paint() are called
5673
 * automatically around expose events sent to the
5674
 * widget. gdk_window_begin_paint() diverts all drawing to a widget's
5675
 * window to an offscreen buffer, and gdk_window_end_paint() draws the
5676
 * buffer to the screen. The result is that users see the window
5677
 * update in one smooth step, and don't see individual graphics
5678
 * primitives being rendered.
5679
 *
5680
 * In very simple terms, double buffered widgets don't flicker,
5681
 * so you would only use this function to turn off double buffering
5682
 * if you had special needs and really knew what you were doing.
5683
 * 
5684
 * Note: if you turn off double-buffering, you have to handle
5685
 * expose events, since even the clearing to the background color or 
5686
 * pixmap will not happen automatically (as it is done in 
5687
 * gdk_window_begin_paint()).
5688
 **/
5689
void
5690
gtk_widget_set_double_buffered (GtkWidget *widget,
5691
				gboolean   double_buffered)
5692
{
5693
  g_return_if_fail (GTK_IS_WIDGET (widget));
5694
5695
  if (double_buffered)
5696
    GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
5697
  else
5698
    GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
5699
}
5700
5701
/**
5702
 * gtk_widget_set_redraw_on_allocate:
5703
 * @widget: a #GtkWidget
5704
 * @redraw_on_allocate: if %TRUE, the entire widget will be redrawn
5705
 *   when it is allocated to a new size. Otherwise, only the
5706
 *   new portion of the widget will be redrawn.
5707
 *
5708
 * Sets whether the entire widget is queued for drawing when its size 
5709
 * allocation changes. By default, this setting is %TRUE and
5710
 * the entire widget is redrawn on every size change. If your widget
5711
 * leaves the upper left unchanged when made bigger, turning this
5712
 * setting off will improve performance.
5713
5714
 * Note that for %NO_WINDOW widgets setting this flag to %FALSE turns
5715
 * off all allocation on resizing: the widget will not even redraw if
5716
 * its position changes; this is to allow containers that don't draw
5717
 * anything to avoid excess invalidations. If you set this flag on a
5718
 * %NO_WINDOW widget that <emphasis>does</emphasis> draw on @widget->window, 
5719
 * you are responsible for invalidating both the old and new allocation 
5720
 * of the widget when the widget is moved and responsible for invalidating
5721
 * regions newly when the widget increases size.
5722
 **/
5723
void
5724
gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
5725
				   gboolean   redraw_on_allocate)
5726
{
5727
  g_return_if_fail (GTK_IS_WIDGET (widget));
5728
5729
  if (redraw_on_allocate)
5730
    GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
5731
  else
5732
    GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
5733
}
5734
5735
/**
5736
 * gtk_widget_set_sensitive:
5737
 * @widget: a #GtkWidget
5738
 * @sensitive: %TRUE to make the widget sensitive
5739
 *
5740
 * Sets the sensitivity of a widget. A widget is sensitive if the user
5741
 * can interact with it. Insensitive widgets are "grayed out" and the
5742
 * user can't interact with them. Insensitive widgets are known as
5743
 * "inactive", "disabled", or "ghosted" in some other toolkits.
5744
 **/
5745
void
5746
gtk_widget_set_sensitive (GtkWidget *widget,
5747
			  gboolean   sensitive)
5748
{
5749
  GtkStateData data;
5750
5751
  g_return_if_fail (GTK_IS_WIDGET (widget));
5752
5753
  sensitive = (sensitive != FALSE);
5754
5755
  if (sensitive == (GTK_WIDGET_SENSITIVE (widget) != FALSE))
5756
    return;
5757
5758
  if (sensitive)
5759
    {
5760
      GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
5761
      data.state = GTK_WIDGET_SAVED_STATE (widget);
5762
    }
5763
  else
5764
    {
5765
      GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
5766
      data.state = GTK_WIDGET_STATE (widget);
5767
    }
5768
  data.state_restoration = TRUE;
5769
  data.use_forall = TRUE;
5770
5771
  if (widget->parent)
5772
    data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget->parent) != FALSE);
5773
  else
5774
    data.parent_sensitive = TRUE;
5775
5776
  gtk_widget_propagate_state (widget, &data);
5777
  if (GTK_WIDGET_DRAWABLE (widget))
5778
    gtk_widget_queue_draw (widget);
5779
5780
  g_object_notify (G_OBJECT (widget), "sensitive");
5781
}
5782
5783
/**
5784
 * gtk_widget_set_parent:
5785
 * @widget: a #GtkWidget
5786
 * @parent: parent container
5787
 *
5788
 * This function is useful only when implementing subclasses of 
5789
 * #GtkContainer.
5790
 * Sets the container as the parent of @widget, and takes care of
5791
 * some details such as updating the state and style of the child
5792
 * to reflect its new location. The opposite function is
5793
 * gtk_widget_unparent().
5794
 **/
5795
void
5796
gtk_widget_set_parent (GtkWidget *widget,
5797
		       GtkWidget *parent)
5798
{
5799
  GtkStateData data;
5800
  
5801
  g_return_if_fail (GTK_IS_WIDGET (widget));
5802
  g_return_if_fail (GTK_IS_WIDGET (parent));
5803
  g_return_if_fail (widget != parent);
5804
  if (widget->parent != NULL)
5805
    {
5806
      g_warning ("Can't set a parent on widget which has a parent\n");
5807
      return;
5808
    }
5809
  if (GTK_WIDGET_TOPLEVEL (widget))
5810
    {
5811
      g_warning ("Can't set a parent on a toplevel widget\n");
5812
      return;
5813
    }
5814
5815
  /* keep this function in sync with gtk_menu_attach_to_widget()
5816
   */
5817
5818
  g_object_ref_sink (widget);
5819
  widget->parent = parent;
5820
5821
  if (GTK_WIDGET_STATE (parent) != GTK_STATE_NORMAL)
5822
    data.state = GTK_WIDGET_STATE (parent);
5823
  else
5824
    data.state = GTK_WIDGET_STATE (widget);
5825
  data.state_restoration = FALSE;
5826
  data.parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (parent) != FALSE);
5827
  data.use_forall = GTK_WIDGET_IS_SENSITIVE (parent) != GTK_WIDGET_IS_SENSITIVE (widget);
5828
5829
  gtk_widget_propagate_state (widget, &data);
5830
  
5831
  gtk_widget_reset_rc_styles (widget);
5832
5833
  g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
5834
  if (GTK_WIDGET_ANCHORED (widget->parent))
5835
    _gtk_widget_propagate_hierarchy_changed (widget, NULL);
5836
  g_object_notify (G_OBJECT (widget), "parent");
5837
5838
  /* Enforce realized/mapped invariants
5839
   */
5840
  if (GTK_WIDGET_REALIZED (widget->parent))
5841
    gtk_widget_realize (widget);
5842
5843
  if (GTK_WIDGET_VISIBLE (widget->parent) &&
5844
      GTK_WIDGET_VISIBLE (widget))
5845
    {
5846
      if (GTK_WIDGET_CHILD_VISIBLE (widget) &&
5847
	  GTK_WIDGET_MAPPED (widget->parent))
5848
	gtk_widget_map (widget);
5849
5850
      gtk_widget_queue_resize (widget);
5851
    }
5852
}
5853
5854
/**
5855
 * gtk_widget_get_parent:
5856
 * @widget: a #GtkWidget
5857
 *
5858
 * Returns the parent container of @widget.
5859
 *
5860
 * Return value: the parent container of @widget, or %NULL
5861
 **/
5862
GtkWidget *
5863
gtk_widget_get_parent (GtkWidget *widget)
5864
{
5865
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5866
5867
  return widget->parent;
5868
}
5869
5870
/*****************************************
5871
 * Widget styles
5872
 * see docs/styles.txt
5873
 *****************************************/
5874
5875
/**
5876
 * gtk_widget_set_style:
5877
 * @widget: a #GtkWidget
5878
 * @style: a #GtkStyle, or %NULL to remove the effect of a previous
5879
 *         gtk_widget_set_style() and go back to the default style
5880
 *
5881
 * Sets the #GtkStyle for a widget (@widget->style). You probably don't
5882
 * want to use this function; it interacts badly with themes, because
5883
 * themes work by replacing the #GtkStyle. Instead, use
5884
 * gtk_widget_modify_style().
5885
 **/
5886
void
5887
gtk_widget_set_style (GtkWidget *widget,
5888
		      GtkStyle	*style)
5889
{
5890
  g_return_if_fail (GTK_IS_WIDGET (widget));
5891
5892
  if (style)
5893
    {
5894
      gboolean initial_emission;
5895
5896
      initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
5897
      
5898
      GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
5899
      GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
5900
      
5901
      gtk_widget_set_style_internal (widget, style, initial_emission);
5902
    }
5903
  else
5904
    {
5905
      if (GTK_WIDGET_USER_STYLE (widget))
5906
	gtk_widget_reset_rc_style (widget);
5907
    }
5908
}
5909
5910
/**
5911
 * gtk_widget_ensure_style:
5912
 * @widget: a #GtkWidget
5913
 *
5914
 * Ensures that @widget has a style (@widget->style). Not a very useful
5915
 * function; most of the time, if you want the style, the widget is
5916
 * realized, and realized widgets are guaranteed to have a style
5917
 * already.
5918
 **/
5919
void
5920
gtk_widget_ensure_style (GtkWidget *widget)
5921
{
5922
  g_return_if_fail (GTK_IS_WIDGET (widget));
5923
5924
  if (!GTK_WIDGET_USER_STYLE (widget) &&
5925
      !GTK_WIDGET_RC_STYLE (widget))
5926
    gtk_widget_reset_rc_style (widget);
5927
}
5928
5929
/* Look up the RC style for this widget, unsetting any user style that
5930
 * may be in effect currently
5931
 **/
5932
static void
5933
gtk_widget_reset_rc_style (GtkWidget *widget)
5934
{
5935
  GtkStyle *new_style = NULL;
5936
  gboolean initial_emission;
5937
  
5938
  initial_emission = !GTK_WIDGET_RC_STYLE (widget) && !GTK_WIDGET_USER_STYLE (widget);
5939
5940
  GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
5941
  GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
5942
  
5943
  if (gtk_widget_has_screen (widget))
5944
    new_style = gtk_rc_get_style (widget);
5945
  if (!new_style)
5946
    new_style = gtk_widget_get_default_style ();
5947
5948
  if (initial_emission || new_style != widget->style)
5949
    gtk_widget_set_style_internal (widget, new_style, initial_emission);
5950
}
5951
5952
/**
5953
 * gtk_widget_get_style:
5954
 * @widget: a #GtkWidget
5955
 * 
5956
 * Simply an accessor function that returns @widget->style.
5957
 * 
5958
 * Return value: the widget's #GtkStyle
5959
 **/
5960
GtkStyle*
5961
gtk_widget_get_style (GtkWidget *widget)
5962
{
5963
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
5964
  
5965
  return widget->style;
5966
}
5967
5968
/**
5969
 * gtk_widget_modify_style:
5970
 * @widget: a #GtkWidget
5971
 * @style: the #GtkRcStyle holding the style modifications
5972
 * 
5973
 * Modifies style values on the widget. Modifications made using this
5974
 * technique take precedence over style values set via an RC file,
5975
 * however, they will be overriden if a style is explicitely set on
5976
 * the widget using gtk_widget_set_style(). The #GtkRcStyle structure
5977
 * is designed so each field can either be set or unset, so it is
5978
 * possible, using this function, to modify some style values and
5979
 * leave the others unchanged.
5980
 *
5981
 * Note that modifications made with this function are not cumulative
5982
 * with previous calls to gtk_widget_modify_style() or with such
5983
 * functions as gtk_widget_modify_fg(). If you wish to retain
5984
 * previous values, you must first call gtk_widget_get_modifier_style(),
5985
 * make your modifications to the returned style, then call
5986
 * gtk_widget_modify_style() with that style. On the other hand,
5987
 * if you first call gtk_widget_modify_style(), subsequent calls
5988
 * to such functions gtk_widget_modify_fg() will have a cumulative
5989
 * effect with the initial modifications.
5990
 **/
5991
void       
5992
gtk_widget_modify_style (GtkWidget      *widget,
5993
			 GtkRcStyle     *style)
5994
{
5995
  g_return_if_fail (GTK_IS_WIDGET (widget));
5996
  g_return_if_fail (GTK_IS_RC_STYLE (style));
5997
  
5998
  g_object_set_qdata_full (G_OBJECT (widget),
5999
			   quark_rc_style,
6000
			   gtk_rc_style_copy (style),
6001
			   (GDestroyNotify) g_object_unref);
6002
6003
  /* note that "style" may be invalid here if it was the old
6004
   * modifier style and the only reference was our own.
6005
   */
6006
  
6007
  if (GTK_WIDGET_RC_STYLE (widget))
6008
    gtk_widget_reset_rc_style (widget);
6009
}
6010
6011
/**
6012
 * gtk_widget_get_modifier_style:
6013
 * @widget: a #GtkWidget
6014
 * 
6015
 * Returns the current modifier style for the widget. (As set by
6016
 * gtk_widget_modify_style().) If no style has previously set, a new
6017
 * #GtkRcStyle will be created with all values unset, and set as the
6018
 * modifier style for the widget. If you make changes to this rc
6019
 * style, you must call gtk_widget_modify_style(), passing in the
6020
 * returned rc style, to make sure that your changes take effect.
6021
 *
6022
 * Caution: passing the style back to gtk_widget_modify_style() will
6023
 * normally end up destroying it, because gtk_widget_modify_style() copies
6024
 * the passed-in style and sets the copy as the new modifier style,
6025
 * thus dropping any reference to the old modifier style. Add a reference
6026
 * to the modifier style if you want to keep it alive.
6027
 * 
6028
 * Return value: the modifier style for the widget. This rc style is
6029
 *   owned by the widget. If you want to keep a pointer to value this
6030
 *   around, you must add a refcount using g_object_ref().
6031
 **/
6032
GtkRcStyle *
6033
gtk_widget_get_modifier_style (GtkWidget      *widget)
6034
{
6035
  GtkRcStyle *rc_style;
6036
  
6037
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6038
6039
  rc_style = g_object_get_qdata (G_OBJECT (widget), quark_rc_style);
6040
6041
  if (!rc_style)
6042
    {
6043
      rc_style = gtk_rc_style_new ();
6044
      g_object_set_qdata_full (G_OBJECT (widget),
6045
			       quark_rc_style,
6046
			       rc_style,
6047
			       (GDestroyNotify) g_object_unref);
6048
    }
6049
6050
  return rc_style;
6051
}
6052
6053
static void
6054
gtk_widget_modify_color_component (GtkWidget      *widget,
6055
				   GtkRcFlags      component,
6056
				   GtkStateType    state,
6057
				   const GdkColor *color)
6058
{
6059
  GtkRcStyle *rc_style = gtk_widget_get_modifier_style (widget);  
6060
6061
  if (color)
6062
    {
6063
      switch (component)
6064
	{
6065
	case GTK_RC_FG:
6066
	  rc_style->fg[state] = *color;
6067
	  break;
6068
	case GTK_RC_BG:
6069
	  rc_style->bg[state] = *color;
6070
	  break;
6071
	case GTK_RC_TEXT:
6072
	  rc_style->text[state] = *color;
6073
	  break;
6074
	case GTK_RC_BASE:
6075
	  rc_style->base[state] = *color;
6076
	  break;
6077
	default:
6078
	  g_assert_not_reached();
6079
	}
6080
      
6081
      rc_style->color_flags[state] |= component;
6082
    }
6083
  else
6084
    rc_style->color_flags[state] &= ~component;
6085
6086
  gtk_widget_modify_style (widget, rc_style);
6087
}
6088
6089
/**
6090
 * gtk_widget_modify_fg:
6091
 * @widget: a #GtkWidget
6092
 * @state: the state for which to set the foreground color
6093
 * @color: the color to assign (does not need to be allocated),
6094
 *         or %NULL to undo the effect of previous calls to
6095
 *         of gtk_widget_modify_fg().
6096
 * 
6097
 * Sets the foreground color for a widget in a particular state.  
6098
 * All other style values are left untouched. See also
6099
 * gtk_widget_modify_style().
6100
 **/
6101
void
6102
gtk_widget_modify_fg (GtkWidget      *widget,
6103
		      GtkStateType    state,
6104
		      const GdkColor *color)
6105
{
6106
  g_return_if_fail (GTK_IS_WIDGET (widget));
6107
  g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
6108
6109
  gtk_widget_modify_color_component (widget, GTK_RC_FG, state, color);
6110
}
6111
6112
/**
6113
 * gtk_widget_modify_bg:
6114
 * @widget: a #GtkWidget
6115
 * @state: the state for which to set the background color
6116
 * @color: the color to assign (does not need to be allocated),
6117
 *         or %NULL to undo the effect of previous calls to
6118
 *         of gtk_widget_modify_bg().
6119
 * 
6120
 * Sets the background color for a widget in a particular state.  
6121
 * All other style values are left untouched. See also
6122
 * gtk_widget_modify_style(). 
6123
 *
6124
 * Note that "no window" widgets (which have the %GTK_NO_WINDOW flag set)
6125
 * draw on their parent container's window and thus may not draw any 
6126
 * background themselves. This is the case for e.g. #GtkLabel. To modify 
6127
 * the background of such widgets, you have to set the background color 
6128
 * on their parent; if you want to set the background of a rectangular 
6129
 * area around a label, try placing the label in a #GtkEventBox widget 
6130
 * and setting the background color on that.
6131
 **/
6132
void
6133
gtk_widget_modify_bg (GtkWidget      *widget,
6134
		      GtkStateType    state,
6135
		      const GdkColor *color)
6136
{
6137
  g_return_if_fail (GTK_IS_WIDGET (widget));
6138
  g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
6139
6140
  gtk_widget_modify_color_component (widget, GTK_RC_BG, state, color);
6141
}
6142
6143
/**
6144
 * gtk_widget_modify_text:
6145
 * @widget: a #GtkWidget
6146
 * @state: the state for which to set the text color
6147
 * @color: the color to assign (does not need to be allocated),
6148
 *         or %NULL to undo the effect of previous calls to
6149
 *         of gtk_widget_modify_text().
6150
 * 
6151
 * Sets the text color for a widget in a particular state.  All other
6152
 * style values are left untouched. The text color is the foreground
6153
 * color used along with the base color (see gtk_widget_modify_base())
6154
 * for widgets such as #GtkEntry and #GtkTextView. See also
6155
 * gtk_widget_modify_style().
6156
 **/
6157
void
6158
gtk_widget_modify_text (GtkWidget      *widget,
6159
			GtkStateType    state,
6160
			const GdkColor *color)
6161
{
6162
  g_return_if_fail (GTK_IS_WIDGET (widget));
6163
  g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
6164
6165
  gtk_widget_modify_color_component (widget, GTK_RC_TEXT, state, color);
6166
}
6167
6168
/**
6169
 * gtk_widget_modify_base:
6170
 * @widget: a #GtkWidget
6171
 * @state: the state for which to set the base color
6172
 * @color: the color to assign (does not need to be allocated),
6173
 *         or %NULL to undo the effect of previous calls to
6174
 *         of gtk_widget_modify_base().
6175
 * 
6176
 * Sets the base color for a widget in a particular state.
6177
 * All other style values are left untouched. The base color
6178
 * is the background color used along with the text color
6179
 * (see gtk_widget_modify_text()) for widgets such as #GtkEntry
6180
 * and #GtkTextView. See also gtk_widget_modify_style().
6181
 *
6182
 * Note that "no window" widgets (which have the %GTK_NO_WINDOW flag set)
6183
 * draw on their parent container's window and thus may not draw any 
6184
 * background themselves. This is the case for e.g. #GtkLabel. To modify 
6185
 * the background of such widgets, you have to set the base color on their 
6186
 * parent; if you want to set the background of a rectangular area around 
6187
 * a label, try placing the label in a #GtkEventBox widget and setting 
6188
 * the base color on that.
6189
 **/
6190
void
6191
gtk_widget_modify_base (GtkWidget      *widget,
6192
			GtkStateType    state,
6193
			const GdkColor *color)
6194
{
6195
  g_return_if_fail (GTK_IS_WIDGET (widget));
6196
  g_return_if_fail (state >= GTK_STATE_NORMAL && state <= GTK_STATE_INSENSITIVE);
6197
6198
  gtk_widget_modify_color_component (widget, GTK_RC_BASE, state, color);
6199
}
6200
6201
static void
6202
modify_color_property (GtkWidget      *widget,
6203
		       GtkRcStyle     *rc_style,
6204
		       const char     *name,
6205
		       const GdkColor *color)
6206
{
6207
  GQuark type_name = g_type_qname (G_OBJECT_TYPE (widget));
6208
  GQuark property_name = g_quark_from_string (name);
6209
6210
  if (color)
6211
    {
6212
      GtkRcProperty rc_property = {0};
6213
      char *color_name;
6214
6215
      rc_property.type_name = type_name;
6216
      rc_property.property_name = property_name;
6217
      rc_property.origin = NULL;
6218
6219
      color_name = gdk_color_to_string (color);
6220
      g_value_init (&rc_property.value, G_TYPE_STRING);
6221
      g_value_take_string (&rc_property.value, color_name);
6222
6223
      _gtk_rc_style_set_rc_property (rc_style, &rc_property);
6224
6225
      g_value_unset (&rc_property.value);
6226
    }
6227
  else
6228
    _gtk_rc_style_unset_rc_property (rc_style, type_name, property_name);
6229
}
6230
6231
/**
6232
 * gtk_widget_modify_cursor:
6233
 * @widget: a #GtkWidget
6234
 * @primary: the color to use for primary cursor (does not need to be
6235
 *           allocated), or %NULL to undo the effect of previous calls to
6236
 *           of gtk_widget_modify_cursor().
6237
 * @secondary: the color to use for secondary cursor (does not need to be
6238
 *             allocated), or %NULL to undo the effect of previous calls to
6239
 *             of gtk_widget_modify_cursor().
6240
 *
6241
 * Sets the cursor color to use in a widget, overriding the
6242
 * #GtkWidget:cursor-color and #GtkWidget:secondary-cursor-color
6243
 * style properties. All other style values are left untouched. 
6244
 * See also gtk_widget_modify_style().
6245
 *
6246
 * Since: 2.12
6247
 **/
6248
void
6249
gtk_widget_modify_cursor (GtkWidget      *widget,
6250
			  const GdkColor *primary,
6251
			  const GdkColor *secondary)
6252
{
6253
  GtkRcStyle *rc_style;
6254
6255
  g_return_if_fail (GTK_IS_WIDGET (widget));
6256
6257
  rc_style = gtk_widget_get_modifier_style (widget);
6258
6259
  modify_color_property (widget, rc_style, "cursor-color", primary);
6260
  modify_color_property (widget, rc_style, "secondary-cursor-color", secondary);
6261
6262
  gtk_widget_modify_style (widget, rc_style);
6263
}
6264
6265
/**
6266
 * gtk_widget_modify_font:
6267
 * @widget: a #GtkWidget
6268
 * @font_desc: the font description to use, or %NULL to undo
6269
 *   the effect of previous calls to gtk_widget_modify_font().
6270
 * 
6271
 * Sets the font to use for a widget.  All other style values are left
6272
 * untouched. See also gtk_widget_modify_style().
6273
 **/
6274
void
6275
gtk_widget_modify_font (GtkWidget            *widget,
6276
			PangoFontDescription *font_desc)
6277
{
6278
  GtkRcStyle *rc_style;
6279
6280
  g_return_if_fail (GTK_IS_WIDGET (widget));
6281
6282
  rc_style = gtk_widget_get_modifier_style (widget);  
6283
6284
  if (rc_style->font_desc)
6285
    pango_font_description_free (rc_style->font_desc);
6286
6287
  if (font_desc)
6288
    rc_style->font_desc = pango_font_description_copy (font_desc);
6289
  else
6290
    rc_style->font_desc = NULL;
6291
  
6292
  gtk_widget_modify_style (widget, rc_style);
6293
}
6294
6295
static void
6296
gtk_widget_real_direction_changed (GtkWidget        *widget,
6297
                                   GtkTextDirection  previous_direction)
6298
{
6299
  gtk_widget_queue_resize (widget);
6300
}
6301
6302
static void
6303
gtk_widget_real_style_set (GtkWidget *widget,
6304
                           GtkStyle  *previous_style)
6305
{
6306
  if (GTK_WIDGET_REALIZED (widget) &&
6307
      !GTK_WIDGET_NO_WINDOW (widget))
6308
    gtk_style_set_background (widget->style, widget->window, widget->state);
6309
}
6310
6311
static void
6312
gtk_widget_set_style_internal (GtkWidget *widget,
6313
			       GtkStyle	 *style,
6314
			       gboolean   initial_emission)
6315
{
6316
  g_object_ref (widget);
6317
  g_object_freeze_notify (G_OBJECT (widget));
6318
6319
  if (widget->style != style)
6320
    {
6321
      GtkStyle *previous_style;
6322
6323
      if (GTK_WIDGET_REALIZED (widget))
6324
	{
6325
	  gtk_widget_reset_shapes (widget);
6326
	  gtk_style_detach (widget->style);
6327
	}
6328
      
6329
      previous_style = widget->style;
6330
      widget->style = style;
6331
      g_object_ref (widget->style);
6332
      
6333
      if (GTK_WIDGET_REALIZED (widget))
6334
	widget->style = gtk_style_attach (widget->style, widget->window);
6335
6336
      gtk_widget_update_pango_context (widget);
6337
      g_signal_emit (widget,
6338
		     widget_signals[STYLE_SET],
6339
		     0,
6340
		     initial_emission ? NULL : previous_style);
6341
      g_object_unref (previous_style);
6342
6343
      if (GTK_WIDGET_ANCHORED (widget) && !initial_emission)
6344
	gtk_widget_queue_resize (widget);
6345
    }
6346
  else if (initial_emission)
6347
    {
6348
      gtk_widget_update_pango_context (widget);
6349
      g_signal_emit (widget,
6350
		     widget_signals[STYLE_SET],
6351
		     0,
6352
		     NULL);
6353
    }
6354
  g_object_notify (G_OBJECT (widget), "style");
6355
  g_object_thaw_notify (G_OBJECT (widget));
6356
  g_object_unref (widget);
6357
}
6358
6359
typedef struct {
6360
  GtkWidget *previous_toplevel;
6361
  GdkScreen *previous_screen;
6362
  GdkScreen *new_screen;
6363
} HierarchyChangedInfo;
6364
6365
static void
6366
do_screen_change (GtkWidget *widget,
6367
		  GdkScreen *old_screen,
6368
		  GdkScreen *new_screen)
6369
{
6370
  if (old_screen != new_screen)
6371
    {
6372
      if (old_screen)
6373
	{
6374
	  PangoContext *context = g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
6375
	  if (context)
6376
	    g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
6377
	}
6378
      
6379
      _gtk_tooltip_hide (widget);
6380
      g_signal_emit (widget, widget_signals[SCREEN_CHANGED], 0, old_screen);
6381
    }
6382
}
6383
6384
static void
6385
gtk_widget_propagate_hierarchy_changed_recurse (GtkWidget *widget,
6386
						gpointer   client_data)
6387
{
6388
  HierarchyChangedInfo *info = client_data;
6389
  gboolean new_anchored = GTK_WIDGET_TOPLEVEL (widget) ||
6390
                 (widget->parent && GTK_WIDGET_ANCHORED (widget->parent));
6391
6392
  if (GTK_WIDGET_ANCHORED (widget) != new_anchored)
6393
    {
6394
      g_object_ref (widget);
6395
      
6396
      if (new_anchored)
6397
	GTK_PRIVATE_SET_FLAG (widget, GTK_ANCHORED);
6398
      else
6399
	GTK_PRIVATE_UNSET_FLAG (widget, GTK_ANCHORED);
6400
      
6401
      g_signal_emit (widget, widget_signals[HIERARCHY_CHANGED], 0, info->previous_toplevel);
6402
      do_screen_change (widget, info->previous_screen, info->new_screen);
6403
      
6404
      if (GTK_IS_CONTAINER (widget))
6405
	gtk_container_forall (GTK_CONTAINER (widget),
6406
			      gtk_widget_propagate_hierarchy_changed_recurse,
6407
			      client_data);
6408
      
6409
      g_object_unref (widget);
6410
    }
6411
}
6412
6413
/**
6414
 * _gtk_widget_propagate_hierarchy_changed:
6415
 * @widget: a #GtkWidget
6416
 * @previous_toplevel: Previous toplevel
6417
 * 
6418
 * Propagates changes in the anchored state to a widget and all
6419
 * children, unsetting or setting the %ANCHORED flag, and
6420
 * emitting #GtkWidget::hierarchy-changed.
6421
 **/
6422
void
6423
_gtk_widget_propagate_hierarchy_changed (GtkWidget    *widget,
6424
					 GtkWidget    *previous_toplevel)
6425
{
6426
  HierarchyChangedInfo info;
6427
6428
  info.previous_toplevel = previous_toplevel;
6429
  info.previous_screen = previous_toplevel ? gtk_widget_get_screen (previous_toplevel) : NULL;
6430
6431
  if (GTK_WIDGET_TOPLEVEL (widget) ||
6432
      (widget->parent && GTK_WIDGET_ANCHORED (widget->parent)))
6433
    info.new_screen = gtk_widget_get_screen (widget);
6434
  else
6435
    info.new_screen = NULL;
6436
6437
  if (info.previous_screen)
6438
    g_object_ref (info.previous_screen);
6439
  if (previous_toplevel)
6440
    g_object_ref (previous_toplevel);
6441
6442
  gtk_widget_propagate_hierarchy_changed_recurse (widget, &info);
6443
6444
  if (previous_toplevel)
6445
    g_object_unref (previous_toplevel);
6446
  if (info.previous_screen)
6447
    g_object_unref (info.previous_screen);
6448
}
6449
6450
static void
6451
gtk_widget_propagate_screen_changed_recurse (GtkWidget *widget,
6452
					     gpointer   client_data)
6453
{
6454
  HierarchyChangedInfo *info = client_data;
6455
6456
  g_object_ref (widget);
6457
  
6458
  do_screen_change (widget, info->previous_screen, info->new_screen);
6459
  
6460
  if (GTK_IS_CONTAINER (widget))
6461
    gtk_container_forall (GTK_CONTAINER (widget),
6462
			  gtk_widget_propagate_screen_changed_recurse,
6463
			  client_data);
6464
  
6465
  g_object_unref (widget);
6466
}
6467
6468
/**
6469
 * gtk_widget_is_composited:
6470
 * @widget: a #GtkWidget
6471
 * 
6472
 * Whether @widget can rely on having its alpha channel
6473
 * drawn correctly. On X11 this function returns whether a
6474
 * compositing manager is running for @widget's screen.
6475
 *
6476
 * Please note that the semantics of this call will change
6477
 * in the future if used on a widget that has a composited
6478
 * window in its heirarchy (as set by
6479
 * gdk_window_set_composited()).
6480
 * 
6481
 * Return value: %TRUE if the widget can rely on its alpha
6482
 * channel being drawn correctly.
6483
 * 
6484
 * Since: 2.10
6485
 */
6486
gboolean
6487
gtk_widget_is_composited (GtkWidget *widget)
6488
{
6489
  GdkScreen *screen;
6490
6491
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6492
  
6493
  screen = gtk_widget_get_screen (widget);
6494
  
6495
  return gdk_screen_is_composited (screen);
6496
}
6497
6498
static void
6499
propagate_composited_changed (GtkWidget *widget,
6500
			      gpointer dummy)
6501
{
6502
  if (GTK_IS_CONTAINER (widget))
6503
    {
6504
      gtk_container_forall (GTK_CONTAINER (widget),
6505
			    propagate_composited_changed,
6506
			    NULL);
6507
    }
6508
  
6509
  g_signal_emit (widget, widget_signals[COMPOSITED_CHANGED], 0);
6510
}
6511
6512
void
6513
_gtk_widget_propagate_composited_changed (GtkWidget *widget)
6514
{
6515
  propagate_composited_changed (widget, NULL);
6516
}
6517
6518
/**
6519
 * _gtk_widget_propagate_screen_changed:
6520
 * @widget: a #GtkWidget
6521
 * @previous_screen: Previous screen
6522
 * 
6523
 * Propagates changes in the screen for a widget to all
6524
 * children, emitting #GtkWidget::screen-changed.
6525
 **/
6526
void
6527
_gtk_widget_propagate_screen_changed (GtkWidget    *widget,
6528
				      GdkScreen    *previous_screen)
6529
{
6530
  HierarchyChangedInfo info;
6531
6532
  info.previous_screen = previous_screen;
6533
  info.new_screen = gtk_widget_get_screen (widget);
6534
6535
  if (previous_screen)
6536
    g_object_ref (previous_screen);
6537
6538
  gtk_widget_propagate_screen_changed_recurse (widget, &info);
6539
6540
  if (previous_screen)
6541
    g_object_unref (previous_screen);
6542
}
6543
6544
static void
6545
reset_rc_styles_recurse (GtkWidget *widget, gpointer data)
6546
{
6547
  if (GTK_WIDGET_RC_STYLE (widget))
6548
    gtk_widget_reset_rc_style (widget);
6549
  
6550
  if (GTK_IS_CONTAINER (widget))
6551
    gtk_container_forall (GTK_CONTAINER (widget),
6552
			  reset_rc_styles_recurse,
6553
			  NULL);
6554
}
6555
6556
void
6557
gtk_widget_reset_rc_styles (GtkWidget *widget)
6558
{
6559
  g_return_if_fail (GTK_IS_WIDGET (widget));
6560
6561
  reset_rc_styles_recurse (widget, NULL);
6562
}
6563
6564
/**
6565
 * gtk_widget_get_default_style:
6566
 * 
6567
 * Returns the default style used by all widgets initially.
6568
 * 
6569
 * Returns: the default style. This #GtkStyle object is owned 
6570
 *          by GTK+ and should not be modified or freed.
6571
 */ 
6572
GtkStyle*
6573
gtk_widget_get_default_style (void)
6574
{
6575
  if (!gtk_default_style)
6576
    {
6577
      gtk_default_style = gtk_style_new ();
6578
      g_object_ref (gtk_default_style);
6579
    }
6580
  
6581
  return gtk_default_style;
6582
}
6583
6584
static PangoContext *
6585
gtk_widget_peek_pango_context (GtkWidget *widget)
6586
{
6587
  return g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
6588
}
6589
6590
/**
6591
 * gtk_widget_get_pango_context:
6592
 * @widget: a #GtkWidget
6593
 * 
6594
 * Gets a #PangoContext with the appropriate font map, font description,
6595
 * and base direction for this widget. Unlike the context returned
6596
 * by gtk_widget_create_pango_context(), this context is owned by
6597
 * the widget (it can be used until the screen for the widget changes
6598
 * or the widget is removed from its toplevel), and will be updated to
6599
 * match any changes to the widget's attributes.
6600
 *
6601
 * If you create and keep a #PangoLayout using this context, you must
6602
 * deal with changes to the context by calling pango_layout_context_changed()
6603
 * on the layout in response to the #GtkWidget::style-set and 
6604
 * #GtkWidget::direction-changed signals for the widget.
6605
 *
6606
 * Return value: the #PangoContext for the widget.
6607
 **/
6608
PangoContext *
6609
gtk_widget_get_pango_context (GtkWidget *widget)
6610
{
6611
  PangoContext *context;
6612
6613
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6614
  
6615
  context = g_object_get_qdata (G_OBJECT (widget), quark_pango_context);
6616
  if (!context)
6617
    {
6618
      context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
6619
      g_object_set_qdata_full (G_OBJECT (widget),
6620
			       quark_pango_context,
6621
			       context,
6622
			       g_object_unref);
6623
    }
6624
6625
  return context;
6626
}
6627
6628
static void
6629
update_pango_context (GtkWidget    *widget,
6630
		      PangoContext *context)
6631
{
6632
  pango_context_set_font_description (context, widget->style->font_desc);
6633
  pango_context_set_base_dir (context,
6634
			      gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
6635
			      PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
6636
}
6637
6638
static void
6639
gtk_widget_update_pango_context (GtkWidget *widget)
6640
{
6641
  PangoContext *context = gtk_widget_peek_pango_context (widget);
6642
  
6643
  if (context)
6644
    {
6645
      GdkScreen *screen;
6646
6647
      update_pango_context (widget, context);
6648
6649
      screen = gtk_widget_get_screen_unchecked (widget);
6650
      if (screen)
6651
	{
6652
	  pango_cairo_context_set_resolution (context,
6653
					      gdk_screen_get_resolution (screen));
6654
	  pango_cairo_context_set_font_options (context,
6655
						gdk_screen_get_font_options (screen));
6656
	}
6657
    }
6658
}
6659
6660
/**
6661
 * gtk_widget_create_pango_context:
6662
 * @widget: a #GtkWidget
6663
 * 
6664
 * Creates a new #PangoContext with the appropriate font map,
6665
 * font description, and base direction for drawing text for
6666
 * this widget. See also gtk_widget_get_pango_context().
6667
 * 
6668
 * Return value: the new #PangoContext
6669
 **/
6670
PangoContext *
6671
gtk_widget_create_pango_context (GtkWidget *widget)
6672
{
6673
  GdkScreen *screen;
6674
  PangoContext *context;
6675
6676
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6677
6678
  screen = gtk_widget_get_screen_unchecked (widget);
6679
  if (!screen)
6680
    {
6681
      GTK_NOTE (MULTIHEAD,
6682
		g_warning ("gtk_widget_create_pango_context ()) called without screen"));
6683
6684
      screen = gdk_screen_get_default ();
6685
    }
6686
6687
  context = gdk_pango_context_get_for_screen (screen);
6688
6689
  update_pango_context (widget, context);
6690
  pango_context_set_language (context, gtk_get_default_language ());
6691
6692
  return context;
6693
}
6694
6695
/**
6696
 * gtk_widget_create_pango_layout:
6697
 * @widget: a #GtkWidget
6698
 * @text: text to set on the layout (can be %NULL)
6699
 * 
6700
 * Creates a new #PangoLayout with the appropriate font map,
6701
 * font description, and base direction for drawing text for
6702
 * this widget.
6703
 *
6704
 * If you keep a #PangoLayout created in this way around, in order to
6705
 * notify the layout of changes to the base direction or font of this
6706
 * widget, you must call pango_layout_context_changed() in response to
6707
 * the #GtkWidget::style-set and #GtkWidget::direction-changed signals 
6708
 * for the widget.
6709
 * 
6710
 * Return value: the new #PangoLayout
6711
 **/
6712
PangoLayout *
6713
gtk_widget_create_pango_layout (GtkWidget   *widget,
6714
				const gchar *text)
6715
{
6716
  PangoLayout *layout;
6717
  PangoContext *context;
6718
6719
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6720
6721
  context = gtk_widget_get_pango_context (widget);
6722
  layout = pango_layout_new (context);
6723
6724
  if (text)
6725
    pango_layout_set_text (layout, text, -1);
6726
6727
  return layout;
6728
}
6729
6730
/**
6731
 * gtk_widget_render_icon:
6732
 * @widget: a #GtkWidget
6733
 * @stock_id: a stock ID
6734
 * @size: a stock size. A size of (GtkIconSize)-1 means render at 
6735
 *     the size of the source and don't scale (if there are multiple 
6736
 *     source sizes, GTK+ picks one of the available sizes).
6737
 * @detail: render detail to pass to theme engine
6738
 * 
6739
 * A convenience function that uses the theme engine and RC file
6740
 * settings for @widget to look up @stock_id and render it to
6741
 * a pixbuf. @stock_id should be a stock icon ID such as
6742
 * #GTK_STOCK_OPEN or #GTK_STOCK_OK. @size should be a size
6743
 * such as #GTK_ICON_SIZE_MENU. @detail should be a string that
6744
 * identifies the widget or code doing the rendering, so that
6745
 * theme engines can special-case rendering for that widget or code.
6746
 *
6747
 * The pixels in the returned #GdkPixbuf are shared with the rest of
6748
 * the application and should not be modified. The pixbuf should be freed
6749
 * after use with g_object_unref().
6750
 *
6751
 * Return value: a new pixbuf, or %NULL if the stock ID wasn't known
6752
 **/
6753
GdkPixbuf*
6754
gtk_widget_render_icon (GtkWidget      *widget,
6755
                        const gchar    *stock_id,
6756
                        GtkIconSize     size,
6757
                        const gchar    *detail)
6758
{
6759
  GtkIconSet *icon_set;
6760
  GdkPixbuf *retval;
6761
  
6762
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6763
  g_return_val_if_fail (stock_id != NULL, NULL);
6764
  g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID || size == -1, NULL);
6765
  
6766
  gtk_widget_ensure_style (widget);
6767
  
6768
  icon_set = gtk_style_lookup_icon_set (widget->style, stock_id);
6769
6770
  if (icon_set == NULL)
6771
    return NULL;
6772
6773
  retval = gtk_icon_set_render_icon (icon_set,
6774
                                     widget->style,
6775
                                     gtk_widget_get_direction (widget),
6776
                                     GTK_WIDGET_STATE (widget),
6777
                                     size,
6778
                                     widget,
6779
                                     detail);
6780
6781
  return retval;
6782
}
6783
6784
/**
6785
 * gtk_widget_set_parent_window:
6786
 * @widget: a #GtkWidget.
6787
 * @parent_window: the new parent window.
6788
 *  
6789
 * Sets a non default parent window for @widget.
6790
 **/
6791
void
6792
gtk_widget_set_parent_window   (GtkWidget           *widget,
6793
				GdkWindow           *parent_window)
6794
{
6795
  GdkWindow *old_parent_window;
6796
6797
  g_return_if_fail (GTK_IS_WIDGET (widget));
6798
  
6799
  old_parent_window = g_object_get_qdata (G_OBJECT (widget),
6800
					  quark_parent_window);
6801
6802
  if (parent_window != old_parent_window)
6803
    {
6804
      g_object_set_qdata (G_OBJECT (widget), quark_parent_window, 
6805
			  parent_window);
6806
      if (old_parent_window)
6807
	g_object_unref (old_parent_window);
6808
      if (parent_window)
6809
	g_object_ref (parent_window);
6810
    }
6811
}
6812
6813
/**
6814
 * gtk_widget_get_parent_window:
6815
 * @widget: a #GtkWidget.
6816
 * @returns: the parent window of @widget.
6817
 *
6818
 * Gets @widget's parent window.
6819
 **/
6820
GdkWindow *
6821
gtk_widget_get_parent_window (GtkWidget *widget)
6822
{
6823
  GdkWindow *parent_window;
6824
6825
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6826
6827
  parent_window = g_object_get_qdata (G_OBJECT (widget), quark_parent_window);
6828
6829
  return (parent_window != NULL) ? parent_window :
6830
	 (widget->parent != NULL) ? widget->parent->window : NULL;
6831
}
6832
6833
6834
/**
6835
 * gtk_widget_set_child_visible:
6836
 * @widget: a #GtkWidget
6837
 * @is_visible: if %TRUE, @widget should be mapped along with its parent.
6838
 *
6839
 * Sets whether @widget should be mapped along with its when its parent
6840
 * is mapped and @widget has been shown with gtk_widget_show(). 
6841
 *
6842
 * The child visibility can be set for widget before it is added to
6843
 * a container with gtk_widget_set_parent(), to avoid mapping
6844
 * children unnecessary before immediately unmapping them. However
6845
 * it will be reset to its default state of %TRUE when the widget
6846
 * is removed from a container.
6847
 * 
6848
 * Note that changing the child visibility of a widget does not
6849
 * queue a resize on the widget. Most of the time, the size of
6850
 * a widget is computed from all visible children, whether or
6851
 * not they are mapped. If this is not the case, the container
6852
 * can queue a resize itself.
6853
 *
6854
 * This function is only useful for container implementations and
6855
 * never should be called by an application.
6856
 **/
6857
void
6858
gtk_widget_set_child_visible (GtkWidget *widget,
6859
			      gboolean   is_visible)
6860
{
6861
  g_return_if_fail (GTK_IS_WIDGET (widget));
6862
  g_return_if_fail (!GTK_WIDGET_TOPLEVEL (widget));
6863
6864
  g_object_ref (widget);
6865
6866
  if (is_visible)
6867
    GTK_PRIVATE_SET_FLAG (widget, GTK_CHILD_VISIBLE);
6868
  else
6869
    {
6870
      GtkWidget *toplevel;
6871
      
6872
      GTK_PRIVATE_UNSET_FLAG (widget, GTK_CHILD_VISIBLE);
6873
6874
      toplevel = gtk_widget_get_toplevel (widget);
6875
      if (toplevel != widget && GTK_WIDGET_TOPLEVEL (toplevel))
6876
	_gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
6877
    }
6878
6879
  if (widget->parent && GTK_WIDGET_REALIZED (widget->parent))
6880
    {
6881
      if (GTK_WIDGET_MAPPED (widget->parent) &&
6882
	  GTK_WIDGET_CHILD_VISIBLE (widget) &&
6883
	  GTK_WIDGET_VISIBLE (widget))
6884
	gtk_widget_map (widget);
6885
      else
6886
	gtk_widget_unmap (widget);
6887
    }
6888
6889
  g_object_unref (widget);
6890
}
6891
6892
/**
6893
 * gtk_widget_get_child_visible:
6894
 * @widget: a #GtkWidget
6895
 * 
6896
 * Gets the value set with gtk_widget_set_child_visible().
6897
 * If you feel a need to use this function, your code probably
6898
 * needs reorganization. 
6899
 *
6900
 * This function is only useful for container implementations and
6901
 * never should be called by an application.
6902
 *
6903
 * Return value: %TRUE if the widget is mapped with the parent.
6904
 **/
6905
gboolean
6906
gtk_widget_get_child_visible (GtkWidget *widget)
6907
{
6908
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6909
  
6910
  return GTK_WIDGET_CHILD_VISIBLE (widget);
6911
}
6912
6913
static GdkScreen *
6914
gtk_widget_get_screen_unchecked (GtkWidget *widget)
6915
{
6916
  GtkWidget *toplevel;
6917
  
6918
  toplevel = gtk_widget_get_toplevel (widget);
6919
6920
  if (GTK_WIDGET_TOPLEVEL (toplevel))
6921
    {
6922
      if (GTK_IS_WINDOW (toplevel))
6923
	return GTK_WINDOW (toplevel)->screen;
6924
      else if (GTK_IS_INVISIBLE (toplevel))
6925
	return GTK_INVISIBLE (widget)->screen;
6926
    }
6927
6928
  return NULL;
6929
}
6930
6931
/**
6932
 * gtk_widget_get_screen:
6933
 * @widget: a #GtkWidget
6934
 * 
6935
 * Get the #GdkScreen from the toplevel window associated with
6936
 * this widget. This function can only be called after the widget
6937
 * has been added to a widget hierarchy with a #GtkWindow
6938
 * at the top.
6939
 *
6940
 * In general, you should only create screen specific
6941
 * resources when a widget has been realized, and you should
6942
 * free those resources when the widget is unrealized.
6943
 * 
6944
 * Return value: the #GdkScreen for the toplevel for this widget.
6945
 *
6946
 * Since: 2.2
6947
 **/
6948
GdkScreen*
6949
gtk_widget_get_screen (GtkWidget *widget)
6950
{
6951
  GdkScreen *screen;
6952
  
6953
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
6954
6955
  screen = gtk_widget_get_screen_unchecked (widget);
6956
6957
  if (screen)
6958
    return screen;
6959
  else
6960
    {
6961
#if 0
6962
      g_warning (G_STRLOC ": Can't get associated screen"
6963
		 " for a widget unless it is inside a toplevel GtkWindow\n"
6964
		 " widget type is %s associated top level type is %s",
6965
		 g_type_name (G_OBJECT_TYPE(G_OBJECT (widget))),
6966
		 g_type_name (G_OBJECT_TYPE(G_OBJECT (toplevel))));
6967
#endif
6968
      return gdk_screen_get_default ();
6969
    }
6970
}
6971
6972
/**
6973
 * gtk_widget_has_screen:
6974
 * @widget: a #GtkWidget
6975
 * 
6976
 * Checks whether there is a #GdkScreen is associated with
6977
 * this widget. All toplevel widgets have an associated
6978
 * screen, and all widgets added into a heirarchy with a toplevel
6979
 * window at the top.
6980
 * 
6981
 * Return value: %TRUE if there is a #GdkScreen associcated
6982
 *   with the widget.
6983
 *
6984
 * Since: 2.2
6985
 **/
6986
gboolean
6987
gtk_widget_has_screen (GtkWidget *widget)
6988
{
6989
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
6990
6991
  return (gtk_widget_get_screen_unchecked (widget) != NULL);
6992
}
6993
6994
/**
6995
 * gtk_widget_get_display:
6996
 * @widget: a #GtkWidget
6997
 * 
6998
 * Get the #GdkDisplay for the toplevel window associated with
6999
 * this widget. This function can only be called after the widget
7000
 * has been added to a widget hierarchy with a #GtkWindow at the top.
7001
 *
7002
 * In general, you should only create display specific
7003
 * resources when a widget has been realized, and you should
7004
 * free those resources when the widget is unrealized.
7005
 * 
7006
 * Return value: the #GdkDisplay for the toplevel for this widget.
7007
 *
7008
 * Since: 2.2
7009
 **/
7010
GdkDisplay*
7011
gtk_widget_get_display (GtkWidget *widget)
7012
{
7013
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7014
  
7015
  return gdk_screen_get_display (gtk_widget_get_screen (widget));
7016
}
7017
7018
/**
7019
 * gtk_widget_get_root_window:
7020
 * @widget: a #GtkWidget
7021
 * 
7022
 * Get the root window where this widget is located. This function can
7023
 * only be called after the widget has been added to a widget
7024
 * heirarchy with #GtkWindow at the top.
7025
 *
7026
 * The root window is useful for such purposes as creating a popup
7027
 * #GdkWindow associated with the window. In general, you should only
7028
 * create display specific resources when a widget has been realized,
7029
 * and you should free those resources when the widget is unrealized.
7030
 * 
7031
 * Return value: the #GdkWindow root window for the toplevel for this widget.
7032
 *
7033
 * Since: 2.2
7034
 **/
7035
GdkWindow*
7036
gtk_widget_get_root_window (GtkWidget *widget)
7037
{
7038
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7039
7040
  return gdk_screen_get_root_window (gtk_widget_get_screen (widget));
7041
}
7042
7043
/**
7044
 * gtk_widget_child_focus:
7045
 * @widget: a #GtkWidget
7046
 * @direction: direction of focus movement
7047
 *
7048
 * This function is used by custom widget implementations; if you're
7049
 * writing an app, you'd use gtk_widget_grab_focus() to move the focus
7050
 * to a particular widget, and gtk_container_set_focus_chain() to
7051
 * change the focus tab order. So you may want to investigate those
7052
 * functions instead.
7053
 * 
7054
 * gtk_widget_child_focus() is called by containers as the user moves
7055
 * around the window using keyboard shortcuts. @direction indicates
7056
 * what kind of motion is taking place (up, down, left, right, tab
7057
 * forward, tab backward). gtk_widget_child_focus() emits the
7058
 * #GtkWidget::focus" signal; widgets override the default handler
7059
 * for this signal in order to implement appropriate focus behavior.
7060
 *
7061
 * The default ::focus handler for a widget should return %TRUE if
7062
 * moving in @direction left the focus on a focusable location inside
7063
 * that widget, and %FALSE if moving in @direction moved the focus
7064
 * outside the widget. If returning %TRUE, widgets normally
7065
 * call gtk_widget_grab_focus() to place the focus accordingly;
7066
 * if returning %FALSE, they don't modify the current focus location.
7067
 * 
7068
 * This function replaces gtk_container_focus() from GTK+ 1.2.  
7069
 * It was necessary to check that the child was visible, sensitive, 
7070
 * and focusable before calling gtk_container_focus(). 
7071
 * gtk_widget_child_focus() returns %FALSE if the widget is not 
7072
 * currently in a focusable state, so there's no need for those checks.
7073
 * 
7074
 * Return value: %TRUE if focus ended up inside @widget
7075
 **/
7076
gboolean
7077
gtk_widget_child_focus (GtkWidget       *widget,
7078
                        GtkDirectionType direction)
7079
{
7080
  gboolean return_val;
7081
7082
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
7083
7084
  if (!GTK_WIDGET_VISIBLE (widget) ||
7085
      !GTK_WIDGET_IS_SENSITIVE (widget))
7086
    return FALSE;
7087
7088
  /* child widgets must set CAN_FOCUS, containers
7089
   * don't have to though.
7090
   */
7091
  if (!GTK_IS_CONTAINER (widget) &&
7092
      !GTK_WIDGET_CAN_FOCUS (widget))
7093
    return FALSE;
7094
  
7095
  g_signal_emit (widget,
7096
		 widget_signals[FOCUS],
7097
		 0,
7098
		 direction, &return_val);
7099
7100
  return return_val;
7101
}
7102
7103
/**
7104
 * gtk_widget_keynav_failed:
7105
 * @widget: a #GtkWidget
7106
 * @direction: direction of focus movement
7107
 *
7108
 * This function should be called whenever keyboard navigation within
7109
 * a single widget hits a boundary. The function emits the
7110
 * #GtkWidget::keynav-failed signal on the widget and its return
7111
 * value should be interpreted in a way similar to the return value of
7112
 * gtk_widget_child_focus():
7113
 *
7114
 * When %TRUE is returned, stay in the widget, the failed keyboard
7115
 * navigation is Ok and/or there is nowhere we can/should move the
7116
 * focus to.
7117
 *
7118
 * When %FALSE is returned, the caller should continue with keyboard
7119
 * navigation outside the widget, e.g. by calling
7120
 * gtk_widget_child_focus() on the widget's toplevel.
7121
 *
7122
 * The default ::keynav-failed handler returns %TRUE for 
7123
 * %GTK_DIR_TAB_FORWARD and %GTK_DIR_TAB_BACKWARD. For the other 
7124
 * values of #GtkDirectionType, it looks at the 
7125
 * #GtkSettings:gtk-keynav-cursor-only setting and returns %FALSE 
7126
 * if the setting is %TRUE. This way the entire user interface
7127
 * becomes cursor-navigatable on input devices such as mobile phones
7128
 * which only have cursor keys but no tab key.
7129
 *
7130
 * Whenever the default handler returns %TRUE, it also calls
7131
 * gtk_widget_error_bell() to notify the user of the failed keyboard
7132
 * navigation.
7133
 *
7134
 * A use case for providing an own implementation of ::keynav-failed 
7135
 * (either by connecting to it or by overriding it) would be a row of
7136
 * #GtkEntry widgets where the user should be able to navigate the
7137
 * entire row with the cursor keys, as e.g. known from user interfaces 
7138
 * that require entering license keys.
7139
 *
7140
 * Return value: %TRUE if stopping keyboard navigation is fine, %FALSE
7141
 *               if the emitting widget should try to handle the keyboard
7142
 *               navigation attempt in its parent container(s).
7143
 *
7144
 * Since: 2.12
7145
 **/
7146
gboolean
7147
gtk_widget_keynav_failed (GtkWidget        *widget,
7148
                          GtkDirectionType  direction)
7149
{
7150
  gboolean return_val;
7151
7152
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
7153
7154
  g_signal_emit (widget, widget_signals[KEYNAV_FAILED], 0,
7155
		 direction, &return_val);
7156
7157
  return return_val;
7158
}
7159
7160
/**
7161
 * gtk_widget_error_bell:
7162
 * @widget: a #GtkWidget
7163
 *
7164
 * Notifies the user about an input-related error on this widget. 
7165
 * If the #GtkSettings:gtk-error-bell setting is %TRUE, it calls
7166
 * gdk_window_beep(), otherwise it does nothing.
7167
 *
7168
 * Note that the effect of gdk_window_beep() can be configured in many
7169
 * ways, depending on the windowing backend and the desktop environment
7170
 * or window manager that is used.
7171
 *
7172
 * Since: 2.12
7173
 **/
7174
void
7175
gtk_widget_error_bell (GtkWidget *widget)
7176
{
7177
  gboolean beep;
7178
7179
  g_return_if_fail (GTK_IS_WIDGET (widget));
7180
7181
  g_object_get (gtk_widget_get_settings (widget),
7182
                "gtk-error-bell", &beep,
7183
                NULL);
7184
7185
  if (beep && widget->window)
7186
    gdk_window_beep (widget->window);
7187
}
7188
7189
/**
7190
 * gtk_widget_set_uposition:
7191
 * @widget: a #GtkWidget
7192
 * @x: x position; -1 to unset x; -2 to leave x unchanged
7193
 * @y: y position; -1 to unset y; -2 to leave y unchanged
7194
 * 
7195
 *
7196
 * Sets the position of a widget. The funny "u" in the name comes from
7197
 * the "user position" hint specified by the X Window System, and
7198
 * exists for legacy reasons. This function doesn't work if a widget
7199
 * is inside a container; it's only really useful on #GtkWindow.
7200
 *
7201
 * Don't use this function to center dialogs over the main application
7202
 * window; most window managers will do the centering on your behalf
7203
 * if you call gtk_window_set_transient_for(), and it's really not
7204
 * possible to get the centering to work correctly in all cases from
7205
 * application code. But if you insist, use gtk_window_set_position()
7206
 * to set #GTK_WIN_POS_CENTER_ON_PARENT, don't do the centering
7207
 * manually.
7208
 *
7209
 * Note that although @x and @y can be individually unset, the position
7210
 * is not honoured unless both @x and @y are set.
7211
 **/
7212
void
7213
gtk_widget_set_uposition (GtkWidget *widget,
7214
			  gint	     x,
7215
			  gint	     y)
7216
{
7217
  /* FIXME this function is the only place that aux_info->x and
7218
   * aux_info->y are even used I believe, and this function is
7219
   * deprecated. Should be cleaned up.
7220
   *
7221
   * (Actually, size_allocate uses them) -Yosh
7222
   */
7223
  
7224
  GtkWidgetAuxInfo *aux_info;
7225
  
7226
  g_return_if_fail (GTK_IS_WIDGET (widget));
7227
  
7228
  aux_info =_gtk_widget_get_aux_info (widget, TRUE);
7229
  
7230
  if (x > -2)
7231
    {
7232
      if (x == -1)
7233
	aux_info->x_set = FALSE;
7234
      else
7235
	{
7236
	  aux_info->x_set = TRUE;
7237
	  aux_info->x = x;
7238
	}
7239
    }
7240
7241
  if (y > -2)
7242
    {
7243
      if (y == -1)
7244
	aux_info->y_set = FALSE;
7245
      else
7246
	{
7247
	  aux_info->y_set = TRUE;
7248
	  aux_info->y = y;
7249
	}
7250
    }
7251
7252
  if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
7253
    _gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
7254
  
7255
  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
7256
    gtk_widget_size_allocate (widget, &widget->allocation);
7257
}
7258
7259
static void
7260
gtk_widget_set_usize_internal (GtkWidget *widget,
7261
			       gint       width,
7262
			       gint       height)
7263
{
7264
  GtkWidgetAuxInfo *aux_info;
7265
  gboolean changed = FALSE;
7266
  
7267
  g_object_freeze_notify (G_OBJECT (widget));
7268
7269
  aux_info = _gtk_widget_get_aux_info (widget, TRUE);
7270
  
7271
  if (width > -2 && aux_info->width != width)
7272
    {
7273
      g_object_notify (G_OBJECT (widget), "width-request");
7274
      aux_info->width = width;
7275
      changed = TRUE;
7276
    }
7277
  if (height > -2 && aux_info->height != height)
7278
    {
7279
      g_object_notify (G_OBJECT (widget), "height-request");  
7280
      aux_info->height = height;
7281
      changed = TRUE;
7282
    }
7283
  
7284
  if (GTK_WIDGET_VISIBLE (widget) && changed)
7285
    gtk_widget_queue_resize (widget);
7286
7287
  g_object_thaw_notify (G_OBJECT (widget));
7288
}
7289
7290
/**
7291
 * gtk_widget_set_usize:
7292
 * @widget: a #GtkWidget
7293
 * @width: minimum width, or -1 to unset
7294
 * @height: minimum height, or -1 to unset
7295
 *
7296
 * Sets the minimum size of a widget; that is, the widget's size
7297
 * request will be @width by @height. You can use this function to
7298
 * force a widget to be either larger or smaller than it is. The
7299
 * strange "usize" name dates from the early days of GTK+, and derives
7300
 * from X Window System terminology. In many cases,
7301
 * gtk_window_set_default_size() is a better choice for toplevel
7302
 * windows than this function; setting the default size will still
7303
 * allow users to shrink the window. Setting the usize will force them
7304
 * to leave the window at least as large as the usize. When dealing
7305
 * with window sizes, gtk_window_set_geometry_hints() can be a useful
7306
 * function as well.
7307
 * 
7308
 * Note the inherent danger of setting any fixed size - themes,
7309
 * translations into other languages, different fonts, and user action
7310
 * can all change the appropriate size for a given widget. So, it's
7311
 * basically impossible to hardcode a size that will always be
7312
 * correct.
7313
 * 
7314
 * Deprecated: 2.2: Use gtk_widget_set_size_request() instead.
7315
 **/
7316
void
7317
gtk_widget_set_usize (GtkWidget *widget,
7318
		      gint	 width,
7319
		      gint	 height)
7320
{
7321
  g_return_if_fail (GTK_IS_WIDGET (widget));
7322
  
7323
  gtk_widget_set_usize_internal (widget, width, height);
7324
}
7325
7326
/**
7327
 * gtk_widget_set_size_request:
7328
 * @widget: a #GtkWidget
7329
 * @width: width @widget should request, or -1 to unset
7330
 * @height: height @widget should request, or -1 to unset
7331
 *
7332
 * Sets the minimum size of a widget; that is, the widget's size
7333
 * request will be @width by @height. You can use this function to
7334
 * force a widget to be either larger or smaller than it normally
7335
 * would be.
7336
 *
7337
 * In most cases, gtk_window_set_default_size() is a better choice for
7338
 * toplevel windows than this function; setting the default size will
7339
 * still allow users to shrink the window. Setting the size request
7340
 * will force them to leave the window at least as large as the size
7341
 * request. When dealing with window sizes,
7342
 * gtk_window_set_geometry_hints() can be a useful function as well.
7343
 * 
7344
 * Note the inherent danger of setting any fixed size - themes,
7345
 * translations into other languages, different fonts, and user action
7346
 * can all change the appropriate size for a given widget. So, it's
7347
 * basically impossible to hardcode a size that will always be
7348
 * correct.
7349
 *
7350
 * The size request of a widget is the smallest size a widget can
7351
 * accept while still functioning well and drawing itself correctly.
7352
 * However in some strange cases a widget may be allocated less than
7353
 * its requested size, and in many cases a widget may be allocated more
7354
 * space than it requested.
7355
 *
7356
 * If the size request in a given direction is -1 (unset), then
7357
 * the "natural" size request of the widget will be used instead.
7358
 *
7359
 * Widgets can't actually be allocated a size less than 1 by 1, but
7360
 * you can pass 0,0 to this function to mean "as small as possible."
7361
 **/
7362
void
7363
gtk_widget_set_size_request (GtkWidget *widget,
7364
                             gint       width,
7365
                             gint       height)
7366
{
7367
  g_return_if_fail (GTK_IS_WIDGET (widget));
7368
  g_return_if_fail (width >= -1);
7369
  g_return_if_fail (height >= -1);
7370
7371
  if (width == 0)
7372
    width = 1;
7373
  if (height == 0)
7374
    height = 1;
7375
  
7376
  gtk_widget_set_usize_internal (widget, width, height);
7377
}
7378
7379
7380
/**
7381
 * gtk_widget_get_size_request:
7382
 * @widget: a #GtkWidget
7383
 * @width: return location for width, or %NULL
7384
 * @height: return location for height, or %NULL
7385
 *
7386
 * Gets the size request that was explicitly set for the widget using
7387
 * gtk_widget_set_size_request(). A value of -1 stored in @width or
7388
 * @height indicates that that dimension has not been set explicitly
7389
 * and the natural requisition of the widget will be used intead. See
7390
 * gtk_widget_set_size_request(). To get the size a widget will
7391
 * actually use, call gtk_widget_size_request() instead of
7392
 * this function.
7393
 **/
7394
void
7395
gtk_widget_get_size_request (GtkWidget *widget,
7396
                             gint      *width,
7397
                             gint      *height)
7398
{
7399
  GtkWidgetAuxInfo *aux_info;
7400
7401
  g_return_if_fail (GTK_IS_WIDGET (widget));
7402
7403
  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
7404
7405
  if (width)
7406
    *width = aux_info ? aux_info->width : -1;
7407
7408
  if (height)
7409
    *height = aux_info ? aux_info->height : -1;
7410
}
7411
7412
/**
7413
 * gtk_widget_set_events:
7414
 * @widget: a #GtkWidget
7415
 * @events: event mask
7416
 *
7417
 * Sets the event mask (see #GdkEventMask) for a widget. The event
7418
 * mask determines which events a widget will receive. Keep in mind
7419
 * that different widgets have different default event masks, and by
7420
 * changing the event mask you may disrupt a widget's functionality,
7421
 * so be careful. This function must be called while a widget is
7422
 * unrealized. Consider gtk_widget_add_events() for widgets that are
7423
 * already realized, or if you want to preserve the existing event
7424
 * mask. This function can't be used with #GTK_NO_WINDOW widgets;
7425
 * to get events on those widgets, place them inside a #GtkEventBox
7426
 * and receive events on the event box.
7427
 **/
7428
void
7429
gtk_widget_set_events (GtkWidget *widget,
7430
		       gint	  events)
7431
{
7432
  g_return_if_fail (GTK_IS_WIDGET (widget));
7433
  g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
7434
  
7435
  g_object_set_qdata (G_OBJECT (widget), quark_event_mask,
7436
                      GINT_TO_POINTER (events));
7437
  g_object_notify (G_OBJECT (widget), "events");
7438
}
7439
7440
static void
7441
gtk_widget_add_events_internal (GtkWidget *widget,
7442
				gint       events,
7443
				GList     *window_list)
7444
{
7445
  GList *l;
7446
7447
  for (l = window_list; l != NULL; l = l->next)
7448
    {
7449
      GdkWindow *window = l->data;
7450
      gpointer user_data;
7451
7452
      gdk_window_get_user_data (window, &user_data);
7453
      if (user_data == widget)
7454
	{
7455
	  GList *children;
7456
7457
	  gdk_window_set_events (window, gdk_window_get_events (window) | events);
7458
7459
	  children = gdk_window_get_children (window);
7460
	  gtk_widget_add_events_internal (widget, events, children);
7461
	  g_list_free (children);
7462
	}
7463
    }
7464
}
7465
7466
/**
7467
 * gtk_widget_add_events:
7468
 * @widget: a #GtkWidget
7469
 * @events: an event mask, see #GdkEventMask
7470
 *
7471
 * Adds the events in the bitfield @events to the event mask for
7472
 * @widget. See gtk_widget_set_events() for details.
7473
 **/
7474
void
7475
gtk_widget_add_events (GtkWidget *widget,
7476
		       gint	  events)
7477
{
7478
  gint old_events;
7479
7480
  g_return_if_fail (GTK_IS_WIDGET (widget));
7481
7482
  old_events = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
7483
  g_object_set_qdata (G_OBJECT (widget), quark_event_mask,
7484
                      GINT_TO_POINTER (old_events | events));
7485
7486
  if (GTK_WIDGET_REALIZED (widget))
7487
    {
7488
      GList *window_list;
7489
7490
      if (GTK_WIDGET_NO_WINDOW (widget))
7491
	window_list = gdk_window_get_children (widget->window);
7492
      else
7493
	window_list = g_list_prepend (NULL, widget->window);
7494
7495
      gtk_widget_add_events_internal (widget, events, window_list);
7496
7497
      g_list_free (window_list);
7498
    }
7499
7500
  g_object_notify (G_OBJECT (widget), "events");
7501
}
7502
7503
/**
7504
 * gtk_widget_set_extension_events:
7505
 * @widget: a #GtkWidget
7506
 * @mode: bitfield of extension events to receive
7507
 *
7508
 * Sets the extension events mask to @mode. See #GdkExtensionMode
7509
 * and gdk_input_set_extension_events().
7510
 **/
7511
void
7512
gtk_widget_set_extension_events (GtkWidget *widget,
7513
				 GdkExtensionMode mode)
7514
{
7515
  g_return_if_fail (GTK_IS_WIDGET (widget));
7516
7517
  if (GTK_WIDGET_REALIZED (widget))
7518
    gtk_widget_set_extension_events_internal (widget, mode, NULL);
7519
7520
  g_object_set_qdata (G_OBJECT (widget), quark_extension_event_mode,
7521
                      GINT_TO_POINTER (mode));
7522
  g_object_notify (G_OBJECT (widget), "extension-events");
7523
}
7524
7525
/**
7526
 * gtk_widget_get_toplevel:
7527
 * @widget: a #GtkWidget
7528
 * 
7529
 * This function returns the topmost widget in the container hierarchy
7530
 * @widget is a part of. If @widget has no parent widgets, it will be
7531
 * returned as the topmost widget. No reference will be added to the
7532
 * returned widget; it should not be unreferenced.
7533
 *
7534
 * Note the difference in behavior vs. gtk_widget_get_ancestor();
7535
 * <literal>gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)</literal> 
7536
 * would return
7537
 * %NULL if @widget wasn't inside a toplevel window, and if the
7538
 * window was inside a #GtkWindow-derived widget which was in turn
7539
 * inside the toplevel #GtkWindow. While the second case may
7540
 * seem unlikely, it actually happens when a #GtkPlug is embedded
7541
 * inside a #GtkSocket within the same application.
7542
 * 
7543
 * To reliably find the toplevel #GtkWindow, use
7544
 * gtk_widget_get_toplevel() and check if the %TOPLEVEL flags
7545
 * is set on the result.
7546
 * |[
7547
 *  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
7548
 *  if (GTK_WIDGET_TOPLEVEL (toplevel))
7549
 *    {
7550
 *      /&ast; Perform action on toplevel. &ast;/
7551
 *    }
7552
 * ]|
7553
 *
7554
 * Return value: the topmost ancestor of @widget, or @widget itself 
7555
 *    if there's no ancestor.
7556
 **/
7557
GtkWidget*
7558
gtk_widget_get_toplevel (GtkWidget *widget)
7559
{
7560
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7561
  
7562
  while (widget->parent)
7563
    widget = widget->parent;
7564
  
7565
  return widget;
7566
}
7567
7568
/**
7569
 * gtk_widget_get_ancestor:
7570
 * @widget: a #GtkWidget
7571
 * @widget_type: ancestor type
7572
 * 
7573
 * Gets the first ancestor of @widget with type @widget_type. For example,
7574
 * <literal>gtk_widget_get_ancestor (widget, GTK_TYPE_BOX)</literal> gets 
7575
 * the first #GtkBox that's an ancestor of @widget. No reference will be 
7576
 * added to the returned widget; it should not be unreferenced. See note 
7577
 * about checking for a toplevel #GtkWindow in the docs for 
7578
 * gtk_widget_get_toplevel().
7579
 * 
7580
 * Note that unlike gtk_widget_is_ancestor(), gtk_widget_get_ancestor() 
7581
 * considers @widget to be an ancestor of itself.
7582
 *
7583
 * Return value: the ancestor widget, or %NULL if not found
7584
 **/
7585
GtkWidget*
7586
gtk_widget_get_ancestor (GtkWidget *widget,
7587
			 GType      widget_type)
7588
{
7589
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7590
  
7591
  while (widget && !g_type_is_a (GTK_WIDGET_TYPE (widget), widget_type))
7592
    widget = widget->parent;
7593
  
7594
  if (!(widget && g_type_is_a (GTK_WIDGET_TYPE (widget), widget_type)))
7595
    return NULL;
7596
  
7597
  return widget;
7598
}
7599
7600
/**
7601
 * gtk_widget_get_colormap:
7602
 * @widget: a #GtkWidget
7603
 * 
7604
 * Gets the colormap that will be used to render @widget. No reference will
7605
 * be added to the returned colormap; it should not be unreferenced.
7606
 * 
7607
 * Return value: the colormap used by @widget
7608
 **/
7609
GdkColormap*
7610
gtk_widget_get_colormap (GtkWidget *widget)
7611
{
7612
  GdkColormap *colormap;
7613
  GtkWidget *tmp_widget;
7614
  
7615
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7616
  
7617
  if (widget->window)
7618
    {
7619
      colormap = gdk_drawable_get_colormap (widget->window);
7620
      /* If window was destroyed previously, we'll get NULL here */
7621
      if (colormap)
7622
	return colormap;
7623
    }
7624
7625
  tmp_widget = widget;
7626
  while (tmp_widget)
7627
    {
7628
      colormap = g_object_get_qdata (G_OBJECT (tmp_widget), quark_colormap);
7629
      if (colormap)
7630
	return colormap;
7631
7632
      tmp_widget= tmp_widget->parent;
7633
    }
7634
7635
  return gdk_screen_get_default_colormap (gtk_widget_get_screen (widget));
7636
}
7637
7638
/**
7639
 * gtk_widget_get_visual:
7640
 * @widget: a #GtkWidget
7641
 * 
7642
 * Gets the visual that will be used to render @widget.
7643
 * 
7644
 * Return value: the visual for @widget
7645
 **/
7646
GdkVisual*
7647
gtk_widget_get_visual (GtkWidget *widget)
7648
{
7649
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7650
7651
  return gdk_colormap_get_visual (gtk_widget_get_colormap (widget));
7652
}
7653
7654
/**
7655
 * gtk_widget_get_settings:
7656
 * @widget: a #GtkWidget
7657
 * 
7658
 * Gets the settings object holding the settings (global property
7659
 * settings, RC file information, etc) used for this widget.
7660
 *
7661
 * Note that this function can only be called when the #GtkWidget
7662
 * is attached to a toplevel, since the settings object is specific
7663
 * to a particular #GdkScreen.
7664
 * 
7665
 * Return value: the relevant #GtkSettings object
7666
 **/
7667
GtkSettings*
7668
gtk_widget_get_settings (GtkWidget *widget)
7669
{
7670
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7671
  
7672
  return gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
7673
}
7674
7675
/**
7676
 * gtk_widget_set_colormap:
7677
 * @widget: a #GtkWidget
7678
 * @colormap: a colormap
7679
 *
7680
 * Sets the colormap for the widget to the given value. Widget must not
7681
 * have been previously realized. This probably should only be used
7682
 * from an <function>init()</function> function (i.e. from the constructor 
7683
 * for the widget).
7684
 **/
7685
void
7686
gtk_widget_set_colormap (GtkWidget   *widget,
7687
                         GdkColormap *colormap)
7688
{
7689
  g_return_if_fail (GTK_IS_WIDGET (widget));
7690
  g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
7691
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
7692
7693
  g_object_ref (colormap);
7694
  
7695
  g_object_set_qdata_full (G_OBJECT (widget), 
7696
			   quark_colormap,
7697
			   colormap,
7698
			   g_object_unref);
7699
}
7700
7701
/**
7702
 * gtk_widget_get_events:
7703
 * @widget: a #GtkWidget
7704
 * 
7705
 * Returns the event mask for the widget (a bitfield containing flags
7706
 * from the #GdkEventMask enumeration). These are the events that the widget
7707
 * will receive.
7708
 * 
7709
 * Return value: event mask for @widget
7710
 **/
7711
gint
7712
gtk_widget_get_events (GtkWidget *widget)
7713
{
7714
  g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
7715
7716
  return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_event_mask));
7717
}
7718
7719
/**
7720
 * gtk_widget_get_extension_events:
7721
 * @widget: a #GtkWidget
7722
 * 
7723
 * Retrieves the extension events the widget will receive; see
7724
 * gdk_input_set_extension_events().
7725
 * 
7726
 * Return value: extension events for @widget
7727
 **/
7728
GdkExtensionMode
7729
gtk_widget_get_extension_events (GtkWidget *widget)
7730
{
7731
  g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
7732
7733
  return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (widget), quark_extension_event_mode));
7734
}
7735
7736
/**
7737
 * gtk_widget_get_pointer:
7738
 * @widget: a #GtkWidget
7739
 * @x: return location for the X coordinate, or %NULL
7740
 * @y: return location for the Y coordinate, or %NULL
7741
 *
7742
 * Obtains the location of the mouse pointer in widget coordinates.
7743
 * Widget coordinates are a bit odd; for historical reasons, they are
7744
 * defined as @widget->window coordinates for widgets that are not
7745
 * #GTK_NO_WINDOW widgets, and are relative to @widget->allocation.x,
7746
 * @widget->allocation.y for widgets that are #GTK_NO_WINDOW widgets.
7747
 **/
7748
void
7749
gtk_widget_get_pointer (GtkWidget *widget,
7750
			gint	  *x,
7751
			gint	  *y)
7752
{
7753
  g_return_if_fail (GTK_IS_WIDGET (widget));
7754
  
7755
  if (x)
7756
    *x = -1;
7757
  if (y)
7758
    *y = -1;
7759
  
7760
  if (GTK_WIDGET_REALIZED (widget))
7761
    {
7762
      gdk_window_get_pointer (widget->window, x, y, NULL);
7763
      
7764
      if (GTK_WIDGET_NO_WINDOW (widget))
7765
	{
7766
	  if (x)
7767
	    *x -= widget->allocation.x;
7768
	  if (y)
7769
	    *y -= widget->allocation.y;
7770
	}
7771
    }
7772
}
7773
7774
/**
7775
 * gtk_widget_is_ancestor:
7776
 * @widget: a #GtkWidget
7777
 * @ancestor: another #GtkWidget
7778
 * 
7779
 * Determines whether @widget is somewhere inside @ancestor, possibly with
7780
 * intermediate containers.
7781
 * 
7782
 * Return value: %TRUE if @ancestor contains @widget as a child, 
7783
 *    grandchild, great grandchild, etc.
7784
 **/
7785
gboolean
7786
gtk_widget_is_ancestor (GtkWidget *widget,
7787
			GtkWidget *ancestor)
7788
{
7789
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
7790
  g_return_val_if_fail (ancestor != NULL, FALSE);
7791
  
7792
  while (widget)
7793
    {
7794
      if (widget->parent == ancestor)
7795
	return TRUE;
7796
      widget = widget->parent;
7797
    }
7798
  
7799
  return FALSE;
7800
}
7801
7802
static GQuark quark_composite_name = 0;
7803
7804
/**
7805
 * gtk_widget_set_composite_name:
7806
 * @widget: a #GtkWidget.
7807
 * @name: the name to set
7808
 * 
7809
 * Sets a widgets composite name. The widget must be
7810
 * a composite child of its parent; see gtk_widget_push_composite_child().
7811
 **/
7812
void
7813
gtk_widget_set_composite_name (GtkWidget   *widget,
7814
			       const gchar *name)
7815
{
7816
  g_return_if_fail (GTK_IS_WIDGET (widget));
7817
  g_return_if_fail (GTK_WIDGET_COMPOSITE_CHILD (widget));
7818
  g_return_if_fail (name != NULL);
7819
7820
  if (!quark_composite_name)
7821
    quark_composite_name = g_quark_from_static_string ("gtk-composite-name");
7822
7823
  g_object_set_qdata_full (G_OBJECT (widget),
7824
			   quark_composite_name,
7825
			   g_strdup (name),
7826
			   g_free);
7827
}
7828
7829
/**
7830
 * gtk_widget_get_composite_name:
7831
 * @widget: a #GtkWidget
7832
 *
7833
 * Obtains the composite name of a widget. 
7834
 *
7835
 * Returns: the composite name of @widget, or %NULL if @widget is not
7836
 *   a composite child. The string should be freed when it is no 
7837
 *   longer needed.
7838
 **/
7839
gchar*
7840
gtk_widget_get_composite_name (GtkWidget *widget)
7841
{
7842
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
7843
7844
  if (GTK_WIDGET_COMPOSITE_CHILD (widget) && widget->parent)
7845
    return _gtk_container_child_composite_name (GTK_CONTAINER (widget->parent),
7846
					       widget);
7847
  else
7848
    return NULL;
7849
}
7850
7851
/**
7852
 * gtk_widget_push_composite_child:
7853
 * 
7854
 * Makes all newly-created widgets as composite children until
7855
 * the corresponding gtk_widget_pop_composite_child() call.
7856
 * 
7857
 * A composite child is a child that's an implementation detail of the
7858
 * container it's inside and should not be visible to people using the
7859
 * container. Composite children aren't treated differently by GTK (but
7860
 * see gtk_container_foreach() vs. gtk_container_forall()), but e.g. GUI 
7861
 * builders might want to treat them in a different way.
7862
 * 
7863
 * Here is a simple example:
7864
 * |[
7865
 *   gtk_widget_push_composite_child ();
7866
 *   scrolled_window->hscrollbar = gtk_hscrollbar_new (hadjustment);
7867
 *   gtk_widget_set_composite_name (scrolled_window->hscrollbar, "hscrollbar");
7868
 *   gtk_widget_pop_composite_child ();
7869
 *   gtk_widget_set_parent (scrolled_window->hscrollbar, 
7870
 *                          GTK_WIDGET (scrolled_window));
7871
 *   g_object_ref (scrolled_window->hscrollbar);
7872
 * ]|
7873
 **/
7874
void
7875
gtk_widget_push_composite_child (void)
7876
{
7877
  composite_child_stack++;
7878
}
7879
7880
/**
7881
 * gtk_widget_pop_composite_child:
7882
 *
7883
 * Cancels the effect of a previous call to gtk_widget_push_composite_child().
7884
 **/ 
7885
void
7886
gtk_widget_pop_composite_child (void)
7887
{
7888
  if (composite_child_stack)
7889
    composite_child_stack--;
7890
}
7891
7892
/**
7893
 * gtk_widget_push_colormap:
7894
 * @cmap: a #GdkColormap
7895
 *
7896
 * Pushes @cmap onto a global stack of colormaps; the topmost
7897
 * colormap on the stack will be used to create all widgets.
7898
 * Remove @cmap with gtk_widget_pop_colormap(). There's little
7899
 * reason to use this function.
7900
 **/
7901
void
7902
gtk_widget_push_colormap (GdkColormap *cmap)
7903
{
7904
  g_return_if_fail (!cmap || GDK_IS_COLORMAP (cmap));
7905
7906
  colormap_stack = g_slist_prepend (colormap_stack, cmap);
7907
}
7908
7909
/**
7910
 * gtk_widget_pop_colormap:
7911
 *
7912
 * Removes a colormap pushed with gtk_widget_push_colormap().
7913
 **/
7914
void
7915
gtk_widget_pop_colormap (void)
7916
{
7917
  if (colormap_stack)
7918
    colormap_stack = g_slist_delete_link (colormap_stack, colormap_stack);
7919
}
7920
7921
/**
7922
 * gtk_widget_set_default_colormap:
7923
 * @colormap: a #GdkColormap
7924
 * 
7925
 * Sets the default colormap to use when creating widgets.
7926
 * gtk_widget_push_colormap() is a better function to use if
7927
 * you only want to affect a few widgets, rather than all widgets.
7928
 **/
7929
void
7930
gtk_widget_set_default_colormap (GdkColormap *colormap)
7931
{
7932
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
7933
  
7934
  gdk_screen_set_default_colormap (gdk_colormap_get_screen (colormap),
7935
				   colormap);
7936
}
7937
7938
/**
7939
 * gtk_widget_get_default_colormap:
7940
 * 
7941
 * Obtains the default colormap used to create widgets.
7942
 * 
7943
 * Return value: default widget colormap
7944
 **/
7945
GdkColormap*
7946
gtk_widget_get_default_colormap (void)
7947
{
7948
  return gdk_screen_get_default_colormap (gdk_screen_get_default ());
7949
}
7950
7951
/**
7952
 * gtk_widget_get_default_visual:
7953
 * 
7954
 * Obtains the visual of the default colormap. Not really useful;
7955
 * used to be useful before gdk_colormap_get_visual() existed.
7956
 * 
7957
 * Return value: visual of the default colormap
7958
 **/
7959
GdkVisual*
7960
gtk_widget_get_default_visual (void)
7961
{
7962
  return gdk_colormap_get_visual (gtk_widget_get_default_colormap ());
7963
}
7964
7965
static void
7966
gtk_widget_emit_direction_changed (GtkWidget        *widget,
7967
				   GtkTextDirection  old_dir)
7968
{
7969
  gtk_widget_update_pango_context (widget);
7970
  
7971
  g_signal_emit (widget, widget_signals[DIRECTION_CHANGED], 0, old_dir);
7972
}
7973
7974
/**
7975
 * gtk_widget_set_direction:
7976
 * @widget: a #GtkWidget
7977
 * @dir:    the new direction
7978
 * 
7979
 * Sets the reading direction on a particular widget. This direction
7980
 * controls the primary direction for widgets containing text,
7981
 * and also the direction in which the children of a container are
7982
 * packed. The ability to set the direction is present in order
7983
 * so that correct localization into languages with right-to-left
7984
 * reading directions can be done. Generally, applications will
7985
 * let the default reading direction present, except for containers
7986
 * where the containers are arranged in an order that is explicitely
7987
 * visual rather than logical (such as buttons for text justification).
7988
 *
7989
 * If the direction is set to %GTK_TEXT_DIR_NONE, then the value
7990
 * set by gtk_widget_set_default_direction() will be used.
7991
 **/
7992
void
7993
gtk_widget_set_direction (GtkWidget        *widget,
7994
			  GtkTextDirection  dir)
7995
{
7996
  GtkTextDirection old_dir;
7997
  
7998
  g_return_if_fail (GTK_IS_WIDGET (widget));
7999
  g_return_if_fail (dir >= GTK_TEXT_DIR_NONE && dir <= GTK_TEXT_DIR_RTL);
8000
8001
  old_dir = gtk_widget_get_direction (widget);
8002
  
8003
  if (dir == GTK_TEXT_DIR_NONE)
8004
    GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_SET);
8005
  else
8006
    {
8007
      GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_SET);
8008
      if (dir == GTK_TEXT_DIR_LTR)
8009
	GTK_PRIVATE_SET_FLAG (widget, GTK_DIRECTION_LTR);
8010
      else
8011
	GTK_PRIVATE_UNSET_FLAG (widget, GTK_DIRECTION_LTR);
8012
    }
8013
8014
  if (old_dir != gtk_widget_get_direction (widget))
8015
    gtk_widget_emit_direction_changed (widget, old_dir);
8016
}
8017
8018
/**
8019
 * gtk_widget_get_direction:
8020
 * @widget: a #GtkWidget
8021
 * 
8022
 * Gets the reading direction for a particular widget. See
8023
 * gtk_widget_set_direction().
8024
 * 
8025
 * Return value: the reading direction for the widget.
8026
 **/
8027
GtkTextDirection
8028
gtk_widget_get_direction (GtkWidget *widget)
8029
{
8030
  g_return_val_if_fail (GTK_IS_WIDGET (widget), GTK_TEXT_DIR_LTR);
8031
  
8032
  if (GTK_WIDGET_DIRECTION_SET (widget))
8033
    return GTK_WIDGET_DIRECTION_LTR (widget) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
8034
  else
8035
    return gtk_default_direction;
8036
}
8037
8038
static void
8039
gtk_widget_set_default_direction_recurse (GtkWidget *widget, gpointer data)
8040
{
8041
  GtkTextDirection old_dir = GPOINTER_TO_UINT (data);
8042
8043
  g_object_ref (widget);
8044
  
8045
  if (!GTK_WIDGET_DIRECTION_SET (widget))
8046
    gtk_widget_emit_direction_changed (widget, old_dir);
8047
  
8048
  if (GTK_IS_CONTAINER (widget))
8049
    gtk_container_forall (GTK_CONTAINER (widget),
8050
			  gtk_widget_set_default_direction_recurse,
8051
			  data);
8052
8053
  g_object_unref (widget);
8054
}
8055
8056
/**
8057
 * gtk_widget_set_default_direction:
8058
 * @dir: the new default direction. This cannot be
8059
 *        %GTK_TEXT_DIR_NONE.
8060
 * 
8061
 * Sets the default reading direction for widgets where the
8062
 * direction has not been explicitly set by gtk_widget_set_direction().
8063
 **/
8064
void
8065
gtk_widget_set_default_direction (GtkTextDirection dir)
8066
{
8067
  g_return_if_fail (dir == GTK_TEXT_DIR_RTL || dir == GTK_TEXT_DIR_LTR);
8068
8069
  if (dir != gtk_default_direction)
8070
    {
8071
      GList *toplevels, *tmp_list;
8072
      GtkTextDirection old_dir = gtk_default_direction;
8073
      
8074
      gtk_default_direction = dir;
8075
8076
      tmp_list = toplevels = gtk_window_list_toplevels ();
8077
      g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
8078
      
8079
      while (tmp_list)
8080
	{
8081
	  gtk_widget_set_default_direction_recurse (tmp_list->data,
8082
						    GUINT_TO_POINTER (old_dir));
8083
	  g_object_unref (tmp_list->data);
8084
	  tmp_list = tmp_list->next;
8085
	}
8086
8087
      g_list_free (toplevels);
8088
    }
8089
}
8090
8091
/**
8092
 * gtk_widget_get_default_direction:
8093
 * 
8094
 * Obtains the current default reading direction. See
8095
 * gtk_widget_set_default_direction().
8096
 *
8097
 * Return value: the current default direction. 
8098
 **/
8099
GtkTextDirection
8100
gtk_widget_get_default_direction (void)
8101
{
8102
  return gtk_default_direction;
8103
}
8104
8105
static void
8106
gtk_widget_dispose (GObject *object)
8107
{
8108
  GtkWidget *widget = GTK_WIDGET (object);
8109
8110
  if (widget->parent)
8111
    gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
8112
  else if (GTK_WIDGET_VISIBLE (widget))
8113
    gtk_widget_hide (widget);
8114
8115
  GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
8116
  if (GTK_WIDGET_REALIZED (widget))
8117
    gtk_widget_unrealize (widget);
8118
  
8119
  G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object);
8120
}
8121
8122
static void
8123
gtk_widget_real_destroy (GtkObject *object)
8124
{
8125
  /* gtk_object_destroy() will already hold a refcount on object */
8126
  GtkWidget *widget = GTK_WIDGET (object);
8127
8128
  /* wipe accelerator closures (keep order) */
8129
  g_object_set_qdata (G_OBJECT (widget), quark_accel_path, NULL);
8130
  g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL);
8131
8132
  /* Callers of add_mnemonic_label() should disconnect on ::destroy */
8133
  g_object_set_qdata (G_OBJECT (widget), quark_mnemonic_labels, NULL);
8134
  
8135
  gtk_grab_remove (widget);
8136
  
8137
  g_object_unref (widget->style);
8138
  widget->style = gtk_widget_get_default_style ();
8139
  g_object_ref (widget->style);
8140
8141
  GTK_OBJECT_CLASS (gtk_widget_parent_class)->destroy (object);
8142
}
8143
8144
static void
8145
gtk_widget_finalize (GObject *object)
8146
{
8147
  GtkWidget *widget = GTK_WIDGET (object);
8148
  GtkWidgetAuxInfo *aux_info;
8149
  GtkAccessible *accessible;
8150
  
8151
  gtk_grab_remove (widget);
8152
8153
  g_object_unref (widget->style);
8154
  widget->style = NULL;
8155
8156
  g_free (widget->name);
8157
  
8158
  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
8159
  if (aux_info)
8160
    gtk_widget_aux_info_destroy (aux_info);
8161
8162
  accessible = g_object_get_qdata (G_OBJECT (widget), quark_accessible_object);
8163
  if (accessible)
8164
    g_object_unref (accessible);
8165
8166
  G_OBJECT_CLASS (gtk_widget_parent_class)->finalize (object);
8167
}
8168
8169
/*****************************************
8170
 * gtk_widget_real_map:
8171
 *
8172
 *   arguments:
8173
 *
8174
 *   results:
8175
 *****************************************/
8176
8177
static void
8178
gtk_widget_real_map (GtkWidget *widget)
8179
{
8180
  g_assert (GTK_WIDGET_REALIZED (widget));
8181
  
8182
  if (!GTK_WIDGET_MAPPED (widget))
8183
    {
8184
      GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
8185
      
8186
      if (!GTK_WIDGET_NO_WINDOW (widget))
8187
	gdk_window_show (widget->window);
8188
    }
8189
}
8190
8191
/*****************************************
8192
 * gtk_widget_real_unmap:
8193
 *
8194
 *   arguments:
8195
 *
8196
 *   results:
8197
 *****************************************/
8198
8199
static void
8200
gtk_widget_real_unmap (GtkWidget *widget)
8201
{
8202
  if (GTK_WIDGET_MAPPED (widget))
8203
    {
8204
      GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
8205
8206
      if (!GTK_WIDGET_NO_WINDOW (widget))
8207
	gdk_window_hide (widget->window);
8208
    }
8209
}
8210
8211
/*****************************************
8212
 * gtk_widget_real_realize:
8213
 *
8214
 *   arguments:
8215
 *
8216
 *   results:
8217
 *****************************************/
8218
8219
static void
8220
gtk_widget_real_realize (GtkWidget *widget)
8221
{
8222
  g_assert (GTK_WIDGET_NO_WINDOW (widget));
8223
  
8224
  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
8225
  if (widget->parent)
8226
    {
8227
      widget->window = gtk_widget_get_parent_window (widget);
8228
      g_object_ref (widget->window);
8229
    }
8230
  widget->style = gtk_style_attach (widget->style, widget->window);
8231
}
8232
8233
/*****************************************
8234
 * gtk_widget_real_unrealize:
8235
 *
8236
 *   arguments:
8237
 *
8238
 *   results:
8239
 *****************************************/
8240
8241
static void
8242
gtk_widget_real_unrealize (GtkWidget *widget)
8243
{
8244
  if (GTK_WIDGET_MAPPED (widget))
8245
    gtk_widget_real_unmap (widget);
8246
8247
  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
8248
8249
  /* printf ("unrealizing %s\n", g_type_name (G_TYPE_FROM_INSTANCE (widget)));
8250
   */
8251
8252
   /* We must do unrealize child widget BEFORE container widget.
8253
    * gdk_window_destroy() destroys specified xwindow and its sub-xwindows.
8254
    * So, unrealizing container widget bofore its children causes the problem 
8255
    * (for example, gdk_ic_destroy () with destroyed window causes crash. )
8256
    */
8257
8258
  if (GTK_IS_CONTAINER (widget))
8259
    gtk_container_forall (GTK_CONTAINER (widget),
8260
			  (GtkCallback) gtk_widget_unrealize,
8261
			  NULL);
8262
8263
  gtk_style_detach (widget->style);
8264
  if (!GTK_WIDGET_NO_WINDOW (widget))
8265
    {
8266
      gdk_window_set_user_data (widget->window, NULL);
8267
      gdk_window_destroy (widget->window);
8268
      widget->window = NULL;
8269
    }
8270
  else
8271
    {
8272
      g_object_unref (widget->window);
8273
      widget->window = NULL;
8274
    }
8275
8276
  gtk_selection_remove_all (widget);
8277
  
8278
  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
8279
}
8280
8281
static void
8282
gtk_widget_real_size_request (GtkWidget         *widget,
8283
			      GtkRequisition    *requisition)
8284
{
8285
  requisition->width = widget->requisition.width;
8286
  requisition->height = widget->requisition.height;
8287
}
8288
8289
/**
8290
 * _gtk_widget_peek_colormap:
8291
 * 
8292
 * Returns colormap currently pushed by gtk_widget_push_colormap, if any.
8293
 * 
8294
 * Return value: the currently pushed colormap, or %NULL if there is none.
8295
 **/
8296
GdkColormap*
8297
_gtk_widget_peek_colormap (void)
8298
{
8299
  if (colormap_stack)
8300
    return (GdkColormap*) colormap_stack->data;
8301
  return NULL;
8302
}
8303
8304
/**
8305
 * _gtk_widget_set_pointer_window:
8306
 * @widget: a #GtkWidget.
8307
 * @pointer_window: the new pointer window.
8308
 *
8309
 * Sets pointer window for @widget.  Does not ref @pointer_window.
8310
 * Actually stores it on the #GdkScreen, but you don't need to know that.
8311
 **/
8312
void
8313
_gtk_widget_set_pointer_window (GtkWidget *widget,
8314
                                GdkWindow *pointer_window)
8315
{
8316
  g_return_if_fail (GTK_IS_WIDGET (widget));
8317
8318
  if (GTK_WIDGET_REALIZED (widget))
8319
    {
8320
      GdkScreen *screen = gdk_drawable_get_screen (widget->window);
8321
8322
      g_object_set_qdata (G_OBJECT (screen), quark_pointer_window,
8323
                          pointer_window);
8324
    }
8325
}
8326
8327
/**
8328
 * _gtk_widget_get_pointer_window:
8329
 * @widget: a #GtkWidget.
8330
 *
8331
 * Return value: the pointer window set on the #GdkScreen @widget is attached
8332
 * to, or %NULL.
8333
 **/
8334
GdkWindow *
8335
_gtk_widget_get_pointer_window (GtkWidget *widget)
8336
{
8337
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
8338
8339
  if (GTK_WIDGET_REALIZED (widget))
8340
    {
8341
      GdkScreen *screen = gdk_drawable_get_screen (widget->window);
8342
8343
      return g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
8344
    }
8345
8346
  return NULL;
8347
}
8348
8349
static void
8350
synth_crossing (GtkWidget      *widget,
8351
		GdkEventType    type,
8352
		GdkWindow      *window,
8353
		GdkCrossingMode mode,
8354
		GdkNotifyType   detail)
8355
{
8356
  GdkEvent *event;
8357
  
8358
  event = gdk_event_new (type);
8359
8360
  event->crossing.window = g_object_ref (window);
8361
  event->crossing.send_event = TRUE;
8362
  event->crossing.subwindow = g_object_ref (window);
8363
  event->crossing.time = GDK_CURRENT_TIME;
8364
  event->crossing.x = event->crossing.y = 0;
8365
  event->crossing.x_root = event->crossing.y_root = 0;
8366
  event->crossing.mode = mode;
8367
  event->crossing.detail = detail;
8368
  event->crossing.focus = FALSE;
8369
  event->crossing.state = 0;
8370
8371
  if (!widget)
8372
    widget = gtk_get_event_widget (event);
8373
8374
  if (widget)
8375
    gtk_widget_event_internal (widget, event);
8376
8377
  gdk_event_free (event);
8378
}
8379
8380
/**
8381
 * _gtk_widget_is_pointer_widget:
8382
 * @widget: a #GtkWidget
8383
 *
8384
 * Returns %TRUE if the pointer window belongs to @widget.
8385
 *
8386
 */
8387
gboolean
8388
_gtk_widget_is_pointer_widget (GtkWidget *widget)
8389
{
8390
  if (GTK_WIDGET_HAS_POINTER (widget))
8391
    { 
8392
      GdkWindow *win; 
8393
      GtkWidget *wid;
8394
8395
      win = _gtk_widget_get_pointer_window (widget);
8396
      if (win)
8397
        { 
8398
          gdk_window_get_user_data (win, &wid);
8399
          if (wid == widget)
8400
            return TRUE;
8401
        }
8402
    }
8403
8404
  return FALSE;
8405
}
8406
8407
/**
8408
 * _gtk_widget_synthesize_crossing:
8409
 * @from: the #GtkWidget the virtual pointer is leaving.
8410
 * @to: the #GtkWidget the virtual pointer is moving to.
8411
 * @mode: the #GdkCrossingMode to place on the synthesized events.
8412
 *
8413
 * Generate crossing event(s) on widget state (sensitivity) or GTK+ grab change.
8414
 *
8415
 * The real pointer window is the window that most recently received an enter notify
8416
 * event.  Windows that don't select for crossing events can't become the real
8417
 * poiner window.  The real pointer widget that owns the real pointer window.  The
8418
 * effective pointer window is the same as the real pointer window unless the real
8419
 * pointer widget is either insensitive or there is a grab on a widget that is not
8420
 * an ancestor of the real pointer widget (in which case the effective pointer
8421
 * window should be the root window).
8422
 *
8423
 * When the effective pointer window is the same as the real poiner window, we
8424
 * receive crossing events from the windowing system.  When the effective pointer
8425
 * window changes to become different from the real pointer window we synthesize
8426
 * crossing events, attempting to follow X protocol rules:
8427
 *
8428
 * When the root window becomes the effective pointer window:
8429
 *   - leave notify on real pointer window, detail Ancestor
8430
 *   - leave notify on all of its ancestors, detail Virtual
8431
 *   - enter notify on root window, detail Inferior
8432
 *
8433
 * When the root window ceases to be the effective pointer window:
8434
 *   - leave notify on root window, detail Inferior
8435
 *   - enter notify on all ancestors of real pointer window, detail Virtual
8436
 *   - enter notify on real pointer window, detail Ancestor
8437
 */
8438
void
8439
_gtk_widget_synthesize_crossing (GtkWidget      *from,
8440
				 GtkWidget      *to,
8441
				 GdkCrossingMode mode)
8442
{
8443
  GdkWindow *from_window = NULL, *to_window = NULL;
8444
8445
  g_return_if_fail (from != NULL || to != NULL);
8446
8447
  if (from != NULL)
8448
    from_window = GTK_WIDGET_HAS_POINTER (from)
8449
      ? _gtk_widget_get_pointer_window (from) : from->window;
8450
  if (to != NULL)
8451
    to_window = GTK_WIDGET_HAS_POINTER (to)
8452
      ? _gtk_widget_get_pointer_window (to) : to->window;
8453
8454
  if (from_window == NULL && to_window == NULL)
8455
    ;
8456
  else if (from_window != NULL && to_window == NULL)
8457
    {
8458
      GList *from_ancestors = NULL, *list;
8459
      GdkWindow *from_ancestor = from_window;
8460
8461
      while (from_ancestor != NULL)
8462
	{
8463
	  if (from_ancestor != NULL)
8464
	    {
8465
	      from_ancestor = gdk_window_get_parent (from_ancestor);
8466
	      if (from_ancestor == NULL)
8467
		break;
8468
	      from_ancestors = g_list_prepend (from_ancestors, from_ancestor);
8469
	    }
8470
	}
8471
8472
      synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
8473
		      mode, GDK_NOTIFY_ANCESTOR);
8474
      for (list = g_list_last (from_ancestors); list; list = list->prev)
8475
	{
8476
	  synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
8477
			  mode, GDK_NOTIFY_VIRTUAL);
8478
	}
8479
8480
      /* XXX: enter/inferior on root window? */
8481
8482
      g_list_free (from_ancestors);
8483
    }
8484
  else if (from_window == NULL && to_window != NULL)
8485
    {
8486
      GList *to_ancestors = NULL, *list;
8487
      GdkWindow *to_ancestor = to_window;
8488
8489
      while (to_ancestor != NULL)
8490
	{
8491
	  if (to_ancestor != NULL)
8492
	    {
8493
	      to_ancestor = gdk_window_get_parent (to_ancestor);
8494
	      if (to_ancestor == NULL)
8495
		break;
8496
	      to_ancestors = g_list_prepend (to_ancestors, to_ancestor);
8497
	    }
8498
	}
8499
8500
      /* XXX: leave/inferior on root window? */
8501
8502
      for (list = to_ancestors; list; list = list->next)
8503
	{
8504
	  synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
8505
			  mode, GDK_NOTIFY_VIRTUAL);
8506
	}
8507
      synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
8508
		      mode, GDK_NOTIFY_ANCESTOR);
8509
8510
      g_list_free (to_ancestors);
8511
    }
8512
  else if (from_window == to_window)
8513
    ;
8514
  else
8515
    {
8516
      GList *from_ancestors = NULL, *to_ancestors = NULL, *list;
8517
      GdkWindow *from_ancestor = from_window, *to_ancestor = to_window;
8518
8519
      while (from_ancestor != NULL || to_ancestor != NULL)
8520
	{
8521
	  if (from_ancestor != NULL)
8522
	    {
8523
	      from_ancestor = gdk_window_get_parent (from_ancestor);
8524
	      if (from_ancestor == to_window)
8525
		break;
8526
	      from_ancestors = g_list_prepend (from_ancestors, from_ancestor);
8527
	    }
8528
	  if (to_ancestor != NULL)
8529
	    {
8530
	      to_ancestor = gdk_window_get_parent (to_ancestor);
8531
	      if (to_ancestor == from_window)
8532
		break;
8533
	      to_ancestors = g_list_prepend (to_ancestors, to_ancestor);
8534
	    }
8535
	}
8536
      if (to_ancestor == from_window)
8537
	{
8538
	  if (mode != GDK_CROSSING_GTK_UNGRAB)
8539
	    synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
8540
			    mode, GDK_NOTIFY_INFERIOR);
8541
	  for (list = to_ancestors; list; list = list->next)
8542
	    synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data, 
8543
			    mode, GDK_NOTIFY_VIRTUAL);
8544
	  synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
8545
			  mode, GDK_NOTIFY_ANCESTOR);
8546
	}
8547
      else if (from_ancestor == to_window)
8548
	{
8549
	  synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
8550
			  mode, GDK_NOTIFY_ANCESTOR);
8551
	  for (list = g_list_last (from_ancestors); list; list = list->prev)
8552
	    {
8553
	      synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
8554
			      mode, GDK_NOTIFY_VIRTUAL);
8555
	    }
8556
	  if (mode != GDK_CROSSING_GTK_GRAB)
8557
	    synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
8558
			    mode, GDK_NOTIFY_INFERIOR);
8559
	}
8560
      else
8561
	{
8562
	  while (from_ancestors != NULL && to_ancestors != NULL 
8563
		 && from_ancestors->data == to_ancestors->data)
8564
	    {
8565
	      from_ancestors = g_list_delete_link (from_ancestors, 
8566
						   from_ancestors);
8567
	      to_ancestors = g_list_delete_link (to_ancestors, to_ancestors);
8568
	    }
8569
8570
	  synth_crossing (from, GDK_LEAVE_NOTIFY, from_window,
8571
			  mode, GDK_NOTIFY_NONLINEAR);
8572
8573
	  for (list = g_list_last (from_ancestors); list; list = list->prev)
8574
	    {
8575
	      synth_crossing (NULL, GDK_LEAVE_NOTIFY, (GdkWindow *) list->data,
8576
			      mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
8577
	    }
8578
	  for (list = to_ancestors; list; list = list->next)
8579
	    {
8580
	      synth_crossing (NULL, GDK_ENTER_NOTIFY, (GdkWindow *) list->data,
8581
			      mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
8582
	    }
8583
	  synth_crossing (to, GDK_ENTER_NOTIFY, to_window,
8584
			  mode, GDK_NOTIFY_NONLINEAR);
8585
	}
8586
      g_list_free (from_ancestors);
8587
      g_list_free (to_ancestors);
8588
    }
8589
}
8590
8591
static void
8592
gtk_widget_propagate_state (GtkWidget           *widget,
8593
			    GtkStateData        *data)
8594
{
8595
  guint8 old_state = GTK_WIDGET_STATE (widget);
8596
  guint8 old_saved_state = GTK_WIDGET_SAVED_STATE (widget);
8597
8598
  /* don't call this function with state==GTK_STATE_INSENSITIVE,
8599
   * parent_sensitive==TRUE on a sensitive widget
8600
   */
8601
8602
8603
  if (data->parent_sensitive)
8604
    GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
8605
  else
8606
    GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
8607
8608
  if (GTK_WIDGET_IS_SENSITIVE (widget))
8609
    {
8610
      if (data->state_restoration)
8611
        GTK_WIDGET_STATE (widget) = GTK_WIDGET_SAVED_STATE (widget);
8612
      else
8613
        GTK_WIDGET_STATE (widget) = data->state;
8614
    }
8615
  else
8616
    {
8617
      if (!data->state_restoration)
8618
	{
8619
	  if (data->state != GTK_STATE_INSENSITIVE)
8620
	    GTK_WIDGET_SAVED_STATE (widget) = data->state;
8621
	}
8622
      else if (GTK_WIDGET_STATE (widget) != GTK_STATE_INSENSITIVE)
8623
	GTK_WIDGET_SAVED_STATE (widget) = GTK_WIDGET_STATE (widget);
8624
      GTK_WIDGET_STATE (widget) = GTK_STATE_INSENSITIVE;
8625
    }
8626
8627
  if (gtk_widget_is_focus (widget) && !GTK_WIDGET_IS_SENSITIVE (widget))
8628
    {
8629
      GtkWidget *window;
8630
8631
      window = gtk_widget_get_toplevel (widget);
8632
      if (window && GTK_WIDGET_TOPLEVEL (window))
8633
	gtk_window_set_focus (GTK_WINDOW (window), NULL);
8634
    }
8635
8636
  if (old_state != GTK_WIDGET_STATE (widget) ||
8637
      old_saved_state != GTK_WIDGET_SAVED_STATE (widget))
8638
    {
8639
      g_object_ref (widget);
8640
8641
      if (!GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_HAS_GRAB (widget))
8642
	gtk_grab_remove (widget);
8643
8644
      g_signal_emit (widget, widget_signals[STATE_CHANGED], 0, old_state);
8645
8646
      if (GTK_WIDGET_HAS_POINTER (widget) && !GTK_WIDGET_SHADOWED (widget))
8647
	{
8648
	  if (!GTK_WIDGET_IS_SENSITIVE (widget))
8649
	    _gtk_widget_synthesize_crossing (widget, NULL, 
8650
					     GDK_CROSSING_STATE_CHANGED);
8651
	  else if (old_state == GTK_STATE_INSENSITIVE)
8652
	    _gtk_widget_synthesize_crossing (NULL, widget, 
8653
					     GDK_CROSSING_STATE_CHANGED);
8654
	}
8655
8656
      if (GTK_IS_CONTAINER (widget))
8657
	{
8658
	  data->parent_sensitive = (GTK_WIDGET_IS_SENSITIVE (widget) != FALSE);
8659
	  if (data->use_forall)
8660
	    gtk_container_forall (GTK_CONTAINER (widget),
8661
				  (GtkCallback) gtk_widget_propagate_state,
8662
				  data);
8663
	  else
8664
	    gtk_container_foreach (GTK_CONTAINER (widget),
8665
				   (GtkCallback) gtk_widget_propagate_state,
8666
				   data);
8667
	}
8668
      g_object_unref (widget);
8669
    }
8670
}
8671
8672
/**
8673
 * _gtk_widget_get_aux_info:
8674
 * @widget: a #GtkWidget
8675
 * @create: if %TRUE, create the structure if it doesn't exist
8676
 * 
8677
 * Get the #GtkWidgetAuxInfo structure for the widget.
8678
 * 
8679
 * Return value: the #GtkAuxInfo structure for the widget, or
8680
 *    %NULL if @create is %FALSE and one doesn't already exist.
8681
 **/
8682
GtkWidgetAuxInfo*
8683
_gtk_widget_get_aux_info (GtkWidget *widget,
8684
			  gboolean   create)
8685
{
8686
  GtkWidgetAuxInfo *aux_info;
8687
  
8688
  aux_info = g_object_get_qdata (G_OBJECT (widget), quark_aux_info);
8689
  if (!aux_info && create)
8690
    {
8691
      aux_info = g_slice_new (GtkWidgetAuxInfo);
8692
8693
      aux_info->width = -1;
8694
      aux_info->height = -1;
8695
      aux_info->x = 0;
8696
      aux_info->y = 0;
8697
      aux_info->x_set = FALSE;
8698
      aux_info->y_set = FALSE;
8699
      g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info);
8700
    }
8701
  
8702
  return aux_info;
8703
}
8704
8705
/*****************************************
8706
 * gtk_widget_aux_info_destroy:
8707
 *
8708
 *   arguments:
8709
 *
8710
 *   results:
8711
 *****************************************/
8712
8713
static void
8714
gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
8715
{
8716
  g_slice_free (GtkWidgetAuxInfo, aux_info);
8717
}
8718
8719
static void
8720
gtk_widget_shape_info_destroy (GtkWidgetShapeInfo *info)
8721
{
8722
  g_object_unref (info->shape_mask);
8723
  g_slice_free (GtkWidgetShapeInfo, info);
8724
}
8725
8726
/**
8727
 * gtk_widget_shape_combine_mask: 
8728
 * @widget: a #GtkWidget
8729
 * @shape_mask: shape to be added, or %NULL to remove an existing shape
8730
 * @offset_x: X position of shape mask with respect to @window
8731
 * @offset_y: Y position of shape mask with respect to @window
8732
 * 
8733
 * Sets a shape for this widget's GDK window. This allows for
8734
 * transparent windows etc., see gdk_window_shape_combine_mask()
8735
 * for more information.
8736
 **/
8737
void
8738
gtk_widget_shape_combine_mask (GtkWidget *widget,
8739
			       GdkBitmap *shape_mask,
8740
			       gint	  offset_x,
8741
			       gint	  offset_y)
8742
{
8743
  GtkWidgetShapeInfo* shape_info;
8744
  
8745
  g_return_if_fail (GTK_IS_WIDGET (widget));
8746
  /*  set_shape doesn't work on widgets without gdk window */
8747
  g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
8748
8749
  if (!shape_mask)
8750
    {
8751
      GTK_PRIVATE_UNSET_FLAG (widget, GTK_HAS_SHAPE_MASK);
8752
      
8753
      if (widget->window)
8754
	gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
8755
      
8756
      g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
8757
    }
8758
  else
8759
    {
8760
      GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
8761
      
8762
      shape_info = g_slice_new (GtkWidgetShapeInfo);
8763
      g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info, shape_info,
8764
			       (GDestroyNotify) gtk_widget_shape_info_destroy);
8765
      
8766
      shape_info->shape_mask = g_object_ref (shape_mask);
8767
      shape_info->offset_x = offset_x;
8768
      shape_info->offset_y = offset_y;
8769
      
8770
      /* set shape if widget has a gdk window already.
8771
       * otherwise the shape is scheduled to be set by gtk_widget_realize().
8772
       */
8773
      if (widget->window)
8774
	gdk_window_shape_combine_mask (widget->window, shape_mask,
8775
				       offset_x, offset_y);
8776
    }
8777
}
8778
8779
/**
8780
 * gtk_widget_input_shape_combine_mask: 
8781
 * @widget: a #GtkWidget
8782
 * @shape_mask: shape to be added, or %NULL to remove an existing shape
8783
 * @offset_x: X position of shape mask with respect to @window
8784
 * @offset_y: Y position of shape mask with respect to @window
8785
 * 
8786
 * Sets an input shape for this widget's GDK window. This allows for
8787
 * windows which react to mouse click in a nonrectangular region, see 
8788
 * gdk_window_input_shape_combine_mask() for more information.
8789
 *
8790
 * Since: 2.10
8791
 **/
8792
void
8793
gtk_widget_input_shape_combine_mask (GtkWidget *widget,
8794
				     GdkBitmap *shape_mask,
8795
				     gint       offset_x,
8796
				     gint	offset_y)
8797
{
8798
  GtkWidgetShapeInfo* shape_info;
8799
  
8800
  g_return_if_fail (GTK_IS_WIDGET (widget));
8801
  /*  set_shape doesn't work on widgets without gdk window */
8802
  g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
8803
8804
  if (!shape_mask)
8805
    {
8806
      if (widget->window)
8807
	gdk_window_input_shape_combine_mask (widget->window, NULL, 0, 0);
8808
      
8809
      g_object_set_qdata (G_OBJECT (widget), quark_input_shape_info, NULL);
8810
    }
8811
  else
8812
    {
8813
      shape_info = g_slice_new (GtkWidgetShapeInfo);
8814
      g_object_set_qdata_full (G_OBJECT (widget), quark_input_shape_info, 
8815
			       shape_info,
8816
			       (GDestroyNotify) gtk_widget_shape_info_destroy);
8817
      
8818
      shape_info->shape_mask = g_object_ref (shape_mask);
8819
      shape_info->offset_x = offset_x;
8820
      shape_info->offset_y = offset_y;
8821
      
8822
      /* set shape if widget has a gdk window already.
8823
       * otherwise the shape is scheduled to be set by gtk_widget_realize().
8824
       */
8825
      if (widget->window)
8826
	gdk_window_input_shape_combine_mask (widget->window, shape_mask,
8827
					     offset_x, offset_y);
8828
    }
8829
}
8830
8831
8832
static void
8833
gtk_reset_shapes_recurse (GtkWidget *widget,
8834
			  GdkWindow *window)
8835
{
8836
  gpointer data;
8837
  GList *list;
8838
8839
  gdk_window_get_user_data (window, &data);
8840
  if (data != widget)
8841
    return;
8842
8843
  gdk_window_shape_combine_mask (window, NULL, 0, 0);
8844
  for (list = gdk_window_peek_children (window); list; list = list->next)
8845
    gtk_reset_shapes_recurse (widget, list->data);
8846
}
8847
8848
/**
8849
 * gtk_widget_reset_shapes:
8850
 * @widget: a #GtkWidget
8851
 *
8852
 * Recursively resets the shape on this widget and its descendants.
8853
 **/
8854
void
8855
gtk_widget_reset_shapes (GtkWidget *widget)
8856
{
8857
  g_return_if_fail (GTK_IS_WIDGET (widget));
8858
  g_return_if_fail (GTK_WIDGET_REALIZED (widget));
8859
8860
  if (!GTK_WIDGET_HAS_SHAPE_MASK (widget))
8861
    gtk_reset_shapes_recurse (widget, widget->window);
8862
}
8863
8864
/**
8865
 * gtk_widget_ref:
8866
 * @widget: a #GtkWidget
8867
 * 
8868
 * Adds a reference to a widget. This function is exactly the same
8869
 * as calling g_object_ref(), and exists mostly for historical
8870
 * reasons. It can still be convenient to avoid casting a widget
8871
 * to a #GObject, it saves a small amount of typing.
8872
 * 
8873
 * Return value: the widget that was referenced
8874
 *
8875
 * Deprecated: 2.12: Use g_object_ref() instead.
8876
 **/
8877
GtkWidget*
8878
gtk_widget_ref (GtkWidget *widget)
8879
{
8880
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
8881
8882
  return (GtkWidget*) g_object_ref ((GObject*) widget);
8883
}
8884
8885
/**
8886
 * gtk_widget_unref:
8887
 * @widget: a #GtkWidget
8888
 *
8889
 * Inverse of gtk_widget_ref(). Equivalent to g_object_unref().
8890
 * 
8891
 * Deprecated: 2.12: Use g_object_unref() instead.
8892
 **/
8893
void
8894
gtk_widget_unref (GtkWidget *widget)
8895
{
8896
  g_return_if_fail (GTK_IS_WIDGET (widget));
8897
8898
  g_object_unref ((GObject*) widget);
8899
}
8900
8901
static void
8902
expose_window (GdkWindow *window)
8903
{
8904
  GdkEvent event;
8905
  GList *l, *children;
8906
  gpointer user_data;
8907
  gboolean is_double_buffered;
8908
8909
  gdk_window_get_user_data (window, &user_data);
8910
8911
  if (user_data)
8912
    is_double_buffered = GTK_WIDGET_DOUBLE_BUFFERED (GTK_WIDGET (user_data));
8913
  else
8914
    is_double_buffered = FALSE;
8915
  
8916
  event.expose.type = GDK_EXPOSE;
8917
  event.expose.window = g_object_ref (window);
8918
  event.expose.send_event = FALSE;
8919
  event.expose.count = 0;
8920
  event.expose.area.x = 0;
8921
  event.expose.area.y = 0;
8922
  gdk_drawable_get_size (GDK_DRAWABLE (window),
8923
			 &event.expose.area.width,
8924
			 &event.expose.area.height);
8925
  event.expose.region = gdk_region_rectangle (&event.expose.area);
8926
8927
  /* If this is not double buffered, force a double buffer so that
8928
     redirection works. */
8929
  if (!is_double_buffered)
8930
    gdk_window_begin_paint_region (window, event.expose.region);
8931
  
8932
  gtk_main_do_event (&event);
8933
8934
  if (!is_double_buffered)
8935
    gdk_window_end_paint (window);
8936
  
8937
  children = gdk_window_peek_children (window);
8938
  for (l = children; l != NULL; l = l->next)
8939
    {
8940
      GdkWindow *child = l->data;
8941
8942
      /* Don't expose input-only windows */
8943
      if (gdk_drawable_get_depth (GDK_DRAWABLE (child)) != 0)
8944
	expose_window (l->data);
8945
    }
8946
  
8947
  g_object_unref (window);
8948
}
8949
8950
/**
8951
 * gtk_widget_get_snapshot:
8952
 * @widget:    a #GtkWidget
8953
 * @clip_rect: a #GdkRectangle or %NULL
8954
 *
8955
 * Create a #GdkPixmap of the contents of the widget and its children.
8956
 *
8957
 * Works even if the widget is obscured. The depth and visual of the
8958
 * resulting pixmap is dependent on the widget being snapshot and likely
8959
 * differs from those of a target widget displaying the pixmap.
8960
 * The function gdk_pixbuf_get_from_drawable() can be used to convert
8961
 * the pixmap to a visual independant representation.
8962
 *
8963
 * The snapshot area used by this function is the @widget's allocation plus
8964
 * any extra space occupied by additional windows belonging to this widget
8965
 * (such as the arrows of a spin button).
8966
 * Thus, the resulting snapshot pixmap is possibly larger than the allocation.
8967
 * 
8968
 * If @clip_rect is non-%NULL, the resulting pixmap is shrunken to
8969
 * match the specified clip_rect. The (x,y) coordinates of @clip_rect are
8970
 * interpreted widget relative. If width or height of @clip_rect are 0 or
8971
 * negative, the width or height of the resulting pixmap will be shrunken
8972
 * by the respective amount.
8973
 * For instance a @clip_rect <literal>{ +5, +5, -10, -10 }</literal> will
8974
 * chop off 5 pixels at each side of the snapshot pixmap.
8975
 * If non-%NULL, @clip_rect will contain the exact widget-relative snapshot
8976
 * coordinates upon return. A @clip_rect of <literal>{ -1, -1, 0, 0 }</literal>
8977
 * can be used to preserve the auto-grown snapshot area and use @clip_rect
8978
 * as a pure output parameter.
8979
 *
8980
 * The returned pixmap can be %NULL, if the resulting @clip_area was empty.
8981
 *
8982
 * Return value: #GdkPixmap snapshot of the widget
8983
 * 
8984
 * Since: 2.14
8985
 **/
8986
GdkPixmap*
8987
gtk_widget_get_snapshot (GtkWidget    *widget,
8988
                         GdkRectangle *clip_rect)
8989
{
8990
  int x, y, width, height;
8991
  GdkWindow *parent_window = NULL;
8992
  GdkPixmap *pixmap;
8993
  GList *windows = NULL, *list;
8994
8995
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
8996
  if (!GTK_WIDGET_VISIBLE (widget))
8997
    return NULL;
8998
8999
  /* the widget (and parent_window) must be realized to be drawable */
9000
  if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
9001
    gtk_widget_realize (widget->parent);
9002
  if (!GTK_WIDGET_REALIZED (widget))
9003
    gtk_widget_realize (widget);
9004
9005
  /* determine snapshot rectangle */
9006
  x = widget->allocation.x;
9007
  y = widget->allocation.y;
9008
  width = widget->allocation.width;
9009
  height = widget->allocation.height;
9010
9011
  if (widget->parent && !GTK_WIDGET_NO_WINDOW (widget))
9012
    {
9013
      /* grow snapshot rectangle to cover all widget windows */
9014
      parent_window = gtk_widget_get_parent_window (widget);
9015
      for (list = gdk_window_peek_children (parent_window); list; list = list->next)
9016
        {
9017
          GdkWindow *subwin = list->data;
9018
          gpointer windata;
9019
          int wx, wy, ww, wh;
9020
          gdk_window_get_user_data (subwin, &windata);
9021
          if (windata != widget)
9022
            continue;
9023
          windows = g_list_prepend (windows, subwin);
9024
          gdk_window_get_position (subwin, &wx, &wy);
9025
          gdk_drawable_get_size (subwin, &ww, &wh);
9026
          /* grow snapshot rectangle by extra widget sub window */
9027
          if (wx < x)
9028
            {
9029
              width += x - wx;
9030
              x = wx;
9031
            }
9032
          if (wy < y)
9033
            {
9034
              height += y - wy;
9035
              y = wy;
9036
            }
9037
          if (x + width < wx + ww)
9038
            width += wx + ww - (x + width);
9039
          if (y + height < wy + wh)
9040
            height += wy + wh - (y + height);
9041
        }
9042
    }
9043
  else if (!widget->parent)
9044
    x = y = 0; /* toplevel */
9045
9046
  /* at this point, (x,y,width,height) is the parent_window relative
9047
   * snapshot area covering all of widget's windows.
9048
   */
9049
9050
  /* shrink snapshot size by clip_rectangle */
9051
  if (clip_rect)
9052
    {
9053
      GdkRectangle snap = { x, y, width, height }, clip = *clip_rect;
9054
      clip.x = clip.x < 0 ? x : clip.x;
9055
      clip.y = clip.y < 0 ? y : clip.y;
9056
      clip.width = clip.width <= 0 ? MAX (0, width + clip.width) : clip.width;
9057
      clip.height = clip.height <= 0 ? MAX (0, height + clip.height) : clip.height;
9058
      if (widget->parent)
9059
        {
9060
          /* offset clip_rect, so it's parent_window relative */
9061
          if (clip_rect->x >= 0)
9062
            clip.x += widget->allocation.x;
9063
          if (clip_rect->y >= 0)
9064
            clip.y += widget->allocation.y;
9065
        }
9066
      if (!gdk_rectangle_intersect (&snap, &clip, &snap))
9067
        {
9068
          g_list_free (windows);
9069
          clip_rect->width = clip_rect->height = 0;
9070
          return NULL; /* empty snapshot area */
9071
        }
9072
      x = snap.x;
9073
      y = snap.y;
9074
      width = snap.width;
9075
      height = snap.height;
9076
    }
9077
9078
  /* render snapshot */
9079
  pixmap = gdk_pixmap_new (widget->window, width, height, gdk_drawable_get_depth (widget->window));
9080
  for (list = windows; list; list = list->next) /* !NO_WINDOW widgets */
9081
    {
9082
      GdkWindow *subwin = list->data;
9083
      int wx, wy;
9084
      if (gdk_drawable_get_depth (GDK_DRAWABLE (subwin)) == 0)
9085
	continue; /* Input only window */
9086
      gdk_window_get_position (subwin, &wx, &wy);
9087
      gdk_window_redirect_to_drawable (subwin, pixmap, MAX (0, x - wx), MAX (0, y - wy),
9088
                                       MAX (0, wx - x), MAX (0, wy - y), width, height);
9089
9090
      expose_window (subwin);
9091
    }
9092
  if (!windows) /* NO_WINDOW || toplevel => parent_window == NULL || parent_window == widget->window */
9093
    {
9094
      gdk_window_redirect_to_drawable (widget->window, pixmap, x, y, 0, 0, width, height);
9095
      expose_window (widget->window);
9096
    }
9097
  for (list = windows; list; list = list->next)
9098
    gdk_window_remove_redirection (list->data);
9099
  if (!windows) /* NO_WINDOW || toplevel */
9100
    gdk_window_remove_redirection (widget->window);
9101
  g_list_free (windows);
9102
9103
  /* return pixmap and snapshot rectangle coordinates */
9104
  if (clip_rect)
9105
    {
9106
      clip_rect->x = x;
9107
      clip_rect->y = y;
9108
      clip_rect->width = width;
9109
      clip_rect->height = height;
9110
      if (widget->parent)
9111
        {
9112
          /* offset clip_rect from parent_window so it's widget relative */
9113
          clip_rect->x -= widget->allocation.x;
9114
          clip_rect->y -= widget->allocation.y;
9115
        }
9116
      if (0)
9117
        g_printerr ("gtk_widget_get_snapshot: %s (%d,%d, %dx%d)\n",
9118
                    G_OBJECT_TYPE_NAME (widget),
9119
                    clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
9120
    }
9121
  return pixmap;
9122
}
9123
9124
/* style properties
9125
 */
9126
9127
/**
9128
 * gtk_widget_class_install_style_property_parser:
9129
 * @klass: a #GtkWidgetClass
9130
 * @pspec: the #GParamSpec for the style property
9131
 * @parser: the parser for the style property
9132
 * 
9133
 * Installs a style property on a widget class. 
9134
 **/
9135
void
9136
gtk_widget_class_install_style_property_parser (GtkWidgetClass     *klass,
9137
						GParamSpec         *pspec,
9138
						GtkRcPropertyParser parser)
9139
{
9140
  g_return_if_fail (GTK_IS_WIDGET_CLASS (klass));
9141
  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
9142
  g_return_if_fail (pspec->flags & G_PARAM_READABLE);
9143
  g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT)));
9144
  
9145
  if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, G_OBJECT_CLASS_TYPE (klass), FALSE))
9146
    {
9147
      g_warning (G_STRLOC ": class `%s' already contains a style property named `%s'",
9148
		 G_OBJECT_CLASS_NAME (klass),
9149
		 pspec->name);
9150
      return;
9151
    }
9152
9153
  g_param_spec_ref_sink (pspec);
9154
  g_param_spec_set_qdata (pspec, quark_property_parser, (gpointer) parser);
9155
  g_param_spec_pool_insert (style_property_spec_pool, pspec, G_OBJECT_CLASS_TYPE (klass));
9156
}
9157
9158
/**
9159
 * gtk_widget_class_install_style_property:
9160
 * @klass: a #GtkWidgetClass
9161
 * @pspec: the #GParamSpec for the property
9162
 * 
9163
 * Installs a style property on a widget class. The parser for the
9164
 * style property is determined by the value type of @pspec.
9165
 **/
9166
void
9167
gtk_widget_class_install_style_property (GtkWidgetClass *klass,
9168
					 GParamSpec     *pspec)
9169
{
9170
  GtkRcPropertyParser parser;
9171
9172
  g_return_if_fail (GTK_IS_WIDGET_CLASS (klass));
9173
  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
9174
9175
  parser = _gtk_rc_property_parser_from_type (G_PARAM_SPEC_VALUE_TYPE (pspec));
9176
9177
  gtk_widget_class_install_style_property_parser (klass, pspec, parser);
9178
}
9179
9180
/**
9181
 * gtk_widget_class_find_style_property:
9182
 * @klass: a #GtkWidgetClass
9183
 * @property_name: the name of the style property to find
9184
 * @returns: the #GParamSpec of the style property or %NULL if @class has no
9185
 *   style property with that name.
9186
 *
9187
 * Finds a style property of a widget class by name.
9188
 *
9189
 * Since: 2.2
9190
 */
9191
GParamSpec*
9192
gtk_widget_class_find_style_property (GtkWidgetClass *klass,
9193
				      const gchar    *property_name)
9194
{
9195
  g_return_val_if_fail (property_name != NULL, NULL);
9196
9197
  return g_param_spec_pool_lookup (style_property_spec_pool,
9198
				   property_name,
9199
				   G_OBJECT_CLASS_TYPE (klass),
9200
				   TRUE);
9201
}
9202
9203
/**
9204
 * gtk_widget_class_list_style_properties:
9205
 * @klass: a #GtkWidgetClass
9206
 * @n_properties: location to return the number of style properties found
9207
 * @returns: an newly allocated array of #GParamSpec*. The array must 
9208
 *       be freed with g_free().
9209
 *
9210
 * Returns all style properties of a widget class.
9211
 *
9212
 * Since: 2.2
9213
 */
9214
GParamSpec**
9215
gtk_widget_class_list_style_properties (GtkWidgetClass *klass,
9216
					guint          *n_properties)
9217
{
9218
  GParamSpec **pspecs;
9219
  guint n;
9220
9221
  pspecs = g_param_spec_pool_list (style_property_spec_pool,
9222
				   G_OBJECT_CLASS_TYPE (klass),
9223
				   &n);
9224
  if (n_properties)
9225
    *n_properties = n;
9226
9227
  return pspecs;
9228
}
9229
9230
/**
9231
 * gtk_widget_style_get_property:
9232
 * @widget: a #GtkWidget
9233
 * @property_name: the name of a style property
9234
 * @value: location to return the property value 
9235
 *
9236
 * Gets the value of a style property of @widget.
9237
 */
9238
void
9239
gtk_widget_style_get_property (GtkWidget   *widget,
9240
			       const gchar *property_name,
9241
			       GValue      *value)
9242
{
9243
  GParamSpec *pspec;
9244
9245
  g_return_if_fail (GTK_IS_WIDGET (widget));
9246
  g_return_if_fail (property_name != NULL);
9247
  g_return_if_fail (G_IS_VALUE (value));
9248
9249
  g_object_ref (widget);
9250
  pspec = g_param_spec_pool_lookup (style_property_spec_pool,
9251
				    property_name,
9252
				    G_OBJECT_TYPE (widget),
9253
				    TRUE);
9254
  if (!pspec)
9255
    g_warning ("%s: widget class `%s' has no property named `%s'",
9256
	       G_STRLOC,
9257
	       G_OBJECT_TYPE_NAME (widget),
9258
	       property_name);
9259
  else
9260
    {
9261
      const GValue *peek_value;
9262
9263
      peek_value = _gtk_style_peek_property_value (widget->style,
9264
						   G_OBJECT_TYPE (widget),
9265
						   pspec,
9266
						   (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser));
9267
      
9268
      /* auto-conversion of the caller's value type
9269
       */
9270
      if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
9271
	g_value_copy (peek_value, value);
9272
      else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
9273
	g_value_transform (peek_value, value);
9274
      else
9275
	g_warning ("can't retrieve style property `%s' of type `%s' as value of type `%s'",
9276
		   pspec->name,
9277
		   g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
9278
		   G_VALUE_TYPE_NAME (value));
9279
    }
9280
  g_object_unref (widget);
9281
}
9282
9283
/**
9284
 * gtk_widget_style_get_valist:
9285
 * @widget: a #GtkWidget
9286
 * @first_property_name: the name of the first property to get
9287
 * @var_args: a <type>va_list</type> of pairs of property names and
9288
 *     locations to return the property values, starting with the location
9289
 *     for @first_property_name.
9290
 * 
9291
 * Non-vararg variant of gtk_widget_style_get(). Used primarily by language 
9292
 * bindings.
9293
 */ 
9294
void
9295
gtk_widget_style_get_valist (GtkWidget   *widget,
9296
			     const gchar *first_property_name,
9297
			     va_list      var_args)
9298
{
9299
  const gchar *name;
9300
9301
  g_return_if_fail (GTK_IS_WIDGET (widget));
9302
9303
  g_object_ref (widget);
9304
9305
  name = first_property_name;
9306
  while (name)
9307
    {
9308
      const GValue *peek_value;
9309
      GParamSpec *pspec;
9310
      gchar *error;
9311
9312
      pspec = g_param_spec_pool_lookup (style_property_spec_pool,
9313
					name,
9314
					G_OBJECT_TYPE (widget),
9315
					TRUE);
9316
      if (!pspec)
9317
	{
9318
	  g_warning ("%s: widget class `%s' has no property named `%s'",
9319
		     G_STRLOC,
9320
		     G_OBJECT_TYPE_NAME (widget),
9321
		     name);
9322
	  break;
9323
	}
9324
      /* style pspecs are always readable so we can spare that check here */
9325
9326
      peek_value = _gtk_style_peek_property_value (widget->style,
9327
						   G_OBJECT_TYPE (widget),
9328
						   pspec,
9329
						   (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser));
9330
      G_VALUE_LCOPY (peek_value, var_args, 0, &error);
9331
      if (error)
9332
	{
9333
	  g_warning ("%s: %s", G_STRLOC, error);
9334
	  g_free (error);
9335
	  break;
9336
	}
9337
9338
      name = va_arg (var_args, gchar*);
9339
    }
9340
9341
  g_object_unref (widget);
9342
}
9343
9344
/**
9345
 * gtk_widget_style_get:
9346
 * @widget: a #GtkWidget
9347
 * @first_property_name: the name of the first property to get
9348
 * @Varargs: pairs of property names and locations to 
9349
 *   return the property values, starting with the location for 
9350
 *   @first_property_name, terminated by %NULL.
9351
 *
9352
 * Gets the values of a multiple style properties of @widget.
9353
 */
9354
void
9355
gtk_widget_style_get (GtkWidget   *widget,
9356
		      const gchar *first_property_name,
9357
		      ...)
9358
{
9359
  va_list var_args;
9360
9361
  g_return_if_fail (GTK_IS_WIDGET (widget));
9362
9363
  va_start (var_args, first_property_name);
9364
  gtk_widget_style_get_valist (widget, first_property_name, var_args);
9365
  va_end (var_args);
9366
}
9367
9368
/**
9369
 * gtk_widget_path:
9370
 * @widget: a #GtkWidget
9371
 * @path_length: location to store length of the path, or %NULL
9372
 * @path: location to store allocated path string, or %NULL 
9373
 * @path_reversed: location to store allocated reverse path string, or %NULL
9374
 *
9375
 * Obtains the full path to @widget. The path is simply the name of a
9376
 * widget and all its parents in the container hierarchy, separated by
9377
 * periods. The name of a widget comes from
9378
 * gtk_widget_get_name(). Paths are used to apply styles to a widget
9379
 * in gtkrc configuration files. Widget names are the type of the
9380
 * widget by default (e.g. "GtkButton") or can be set to an
9381
 * application-specific value with gtk_widget_set_name(). By setting
9382
 * the name of a widget, you allow users or theme authors to apply
9383
 * styles to that specific widget in their gtkrc
9384
 * file. @path_reversed_p fills in the path in reverse order,
9385
 * i.e. starting with @widget's name instead of starting with the name
9386
 * of @widget's outermost ancestor.
9387
 **/
9388
void
9389
gtk_widget_path (GtkWidget *widget,
9390
		 guint     *path_length,
9391
		 gchar    **path,
9392
		 gchar    **path_reversed)
9393
{
9394
  static gchar *rev_path = NULL;
9395
  static guint tmp_path_len = 0;
9396
  guint len;
9397
  
9398
  g_return_if_fail (GTK_IS_WIDGET (widget));
9399
  
9400
  len = 0;
9401
  do
9402
    {
9403
      const gchar *string;
9404
      const gchar *s;
9405
      gchar *d;
9406
      guint l;
9407
      
9408
      string = gtk_widget_get_name (widget);
9409
      l = strlen (string);
9410
      while (tmp_path_len <= len + l + 1)
9411
	{
9412
	  tmp_path_len += INIT_PATH_SIZE;
9413
	  rev_path = g_realloc (rev_path, tmp_path_len);
9414
	}
9415
      s = string + l - 1;
9416
      d = rev_path + len;
9417
      while (s >= string)
9418
	*(d++) = *(s--);
9419
      len += l;
9420
      
9421
      widget = widget->parent;
9422
      
9423
      if (widget)
9424
	rev_path[len++] = '.';
9425
      else
9426
	rev_path[len++] = 0;
9427
    }
9428
  while (widget);
9429
  
9430
  if (path_length)
9431
    *path_length = len - 1;
9432
  if (path_reversed)
9433
    *path_reversed = g_strdup (rev_path);
9434
  if (path)
9435
    {
9436
      *path = g_strdup (rev_path);
9437
      g_strreverse (*path);
9438
    }
9439
}
9440
9441
/**
9442
 * gtk_widget_class_path:
9443
 * @widget: a #GtkWidget
9444
 * @path_length: location to store the length of the class path, or %NULL
9445
 * @path: location to store the class path as an allocated string, or %NULL
9446
 * @path_reversed: location to store the reverse class path as an allocated 
9447
 *    string, or %NULL
9448
 *
9449
 * Same as gtk_widget_path(), but always uses the name of a widget's type,
9450
 * never uses a custom name set with gtk_widget_set_name().
9451
 * 
9452
 **/
9453
void
9454
gtk_widget_class_path (GtkWidget *widget,
9455
		       guint     *path_length,
9456
		       gchar    **path,
9457
		       gchar    **path_reversed)
9458
{
9459
  static gchar *rev_path = NULL;
9460
  static guint tmp_path_len = 0;
9461
  guint len;
9462
  
9463
  g_return_if_fail (GTK_IS_WIDGET (widget));
9464
  
9465
  len = 0;
9466
  do
9467
    {
9468
      const gchar *string;
9469
      const gchar *s;
9470
      gchar *d;
9471
      guint l;
9472
      
9473
      string = g_type_name (GTK_WIDGET_TYPE (widget));
9474
      l = strlen (string);
9475
      while (tmp_path_len <= len + l + 1)
9476
	{
9477
	  tmp_path_len += INIT_PATH_SIZE;
9478
	  rev_path = g_realloc (rev_path, tmp_path_len);
9479
	}
9480
      s = string + l - 1;
9481
      d = rev_path + len;
9482
      while (s >= string)
9483
	*(d++) = *(s--);
9484
      len += l;
9485
      
9486
      widget = widget->parent;
9487
      
9488
      if (widget)
9489
	rev_path[len++] = '.';
9490
      else
9491
	rev_path[len++] = 0;
9492
    }
9493
  while (widget);
9494
  
9495
  if (path_length)
9496
    *path_length = len - 1;
9497
  if (path_reversed)
9498
    *path_reversed = g_strdup (rev_path);
9499
  if (path)
9500
    {
9501
      *path = g_strdup (rev_path);
9502
      g_strreverse (*path);
9503
    }
9504
}
9505
9506
/**
9507
 * gtk_requisition_copy:
9508
 * @requisition: a #GtkRequisition
9509
 *
9510
 * Copies a #GtkRequisition.
9511
 *
9512
 * Returns: a copy of @requisition
9513
 **/
9514
GtkRequisition *
9515
gtk_requisition_copy (const GtkRequisition *requisition)
9516
{
9517
  return (GtkRequisition *)g_memdup (requisition, sizeof (GtkRequisition));
9518
}
9519
9520
/**
9521
 * gtk_requisition_free:
9522
 * @requisition: a #GtkRequisition
9523
 * 
9524
 * Frees a #GtkRequisition.
9525
 **/
9526
void
9527
gtk_requisition_free (GtkRequisition *requisition)
9528
{
9529
  g_free (requisition);
9530
}
9531
9532
GType
9533
gtk_requisition_get_type (void)
9534
{
9535
  static GType our_type = 0;
9536
  
9537
  if (our_type == 0)
9538
    our_type = g_boxed_type_register_static (I_("GtkRequisition"),
9539
					     (GBoxedCopyFunc) gtk_requisition_copy,
9540
					     (GBoxedFreeFunc) gtk_requisition_free);
9541
9542
  return our_type;
9543
}
9544
9545
/**
9546
 * gtk_widget_get_accessible:
9547
 * @widget: a #GtkWidget
9548
 *
9549
 * Returns the accessible object that describes the widget to an
9550
 * assistive technology. 
9551
 * 
9552
 * If no accessibility library is loaded (i.e. no ATK implementation library is 
9553
 * loaded via <envar>GTK_MODULES</envar> or via another application library, 
9554
 * such as libgnome), then this #AtkObject instance may be a no-op. Likewise, 
9555
 * if no class-specific #AtkObject implementation is available for the widget 
9556
 * instance in question, it will inherit an #AtkObject implementation from the 
9557
 * first ancestor class for which such an implementation is defined.
9558
 *
9559
 * The documentation of the <ulink url="http://developer.gnome.org/doc/API/2.0/atk/index.html">ATK</ulink>
9560
 * library contains more information about accessible objects and their uses.
9561
 * 
9562
 * Returns: the #AtkObject associated with @widget
9563
 */
9564
AtkObject* 
9565
gtk_widget_get_accessible (GtkWidget *widget)
9566
{
9567
  GtkWidgetClass *klass;
9568
9569
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
9570
9571
  klass = GTK_WIDGET_GET_CLASS (widget);
9572
9573
  g_return_val_if_fail (klass->get_accessible != NULL, NULL);
9574
9575
  return klass->get_accessible (widget);
9576
}
9577
9578
static AtkObject* 
9579
gtk_widget_real_get_accessible (GtkWidget *widget)
9580
{
9581
  AtkObject* accessible;
9582
9583
  accessible = g_object_get_qdata (G_OBJECT (widget), 
9584
                                   quark_accessible_object);
9585
  if (!accessible)
9586
  {
9587
    AtkObjectFactory *factory;
9588
    AtkRegistry *default_registry;
9589
9590
    default_registry = atk_get_default_registry ();
9591
    factory = atk_registry_get_factory (default_registry, 
9592
                                        G_TYPE_FROM_INSTANCE (widget));
9593
    accessible =
9594
      atk_object_factory_create_accessible (factory,
9595
					    G_OBJECT (widget));
9596
    g_object_set_qdata (G_OBJECT (widget), 
9597
                        quark_accessible_object,
9598
                        accessible);
9599
  }
9600
  return accessible;
9601
}
9602
9603
/*
9604
 * Initialize a AtkImplementorIface instance's virtual pointers as
9605
 * appropriate to this implementor's class (GtkWidget).
9606
 */
9607
static void
9608
gtk_widget_accessible_interface_init (AtkImplementorIface *iface)
9609
{
9610
  iface->ref_accessible = gtk_widget_ref_accessible;
9611
}
9612
9613
static AtkObject*
9614
gtk_widget_ref_accessible (AtkImplementor *implementor)
9615
{
9616
  AtkObject *accessible;
9617
9618
  accessible = gtk_widget_get_accessible (GTK_WIDGET (implementor));
9619
  if (accessible)
9620
    g_object_ref (accessible);
9621
  return accessible;
9622
}
9623
9624
/*
9625
 * GtkBuildable implementation
9626
 */
9627
static GQuark		 quark_builder_has_default = 0;
9628
static GQuark		 quark_builder_has_focus = 0;
9629
static GQuark		 quark_builder_atk_relations = 0;
9630
static GQuark            quark_builder_set_name = 0;
9631
9632
static void
9633
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
9634
{
9635
  quark_builder_has_default = g_quark_from_static_string ("gtk-builder-has-default");
9636
  quark_builder_has_focus = g_quark_from_static_string ("gtk-builder-has-focus");
9637
  quark_builder_atk_relations = g_quark_from_static_string ("gtk-builder-atk-relations");
9638
  quark_builder_set_name = g_quark_from_static_string ("gtk-builder-set-name");
9639
9640
  iface->set_name = gtk_widget_buildable_set_name;
9641
  iface->get_name = gtk_widget_buildable_get_name;
9642
  iface->get_internal_child = gtk_widget_buildable_get_internal_child;
9643
  iface->set_buildable_property = gtk_widget_buildable_set_buildable_property;
9644
  iface->parser_finished = gtk_widget_buildable_parser_finished;
9645
  iface->custom_tag_start = gtk_widget_buildable_custom_tag_start;
9646
  iface->custom_finished = gtk_widget_buildable_custom_finished;
9647
}
9648
9649
static void
9650
gtk_widget_buildable_set_name (GtkBuildable *buildable,
9651
			       const gchar  *name)
9652
{
9653
  g_object_set_qdata_full (G_OBJECT (buildable), quark_builder_set_name,
9654
                           g_strdup (name), g_free);
9655
}
9656
9657
static const gchar *
9658
gtk_widget_buildable_get_name (GtkBuildable *buildable)
9659
{
9660
  return g_object_get_qdata (G_OBJECT (buildable), quark_builder_set_name);
9661
}
9662
9663
static GObject *
9664
gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
9665
					 GtkBuilder   *builder,
9666
					 const gchar  *childname)
9667
{
9668
  if (strcmp (childname, "accessible") == 0)
9669
    return G_OBJECT (gtk_widget_get_accessible (GTK_WIDGET (buildable)));
9670
9671
  return NULL;
9672
}
9673
9674
static void
9675
gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
9676
					     GtkBuilder   *builder,
9677
					     const gchar  *name,
9678
					     const GValue *value)
9679
{
9680
  if (strcmp (name, "has-default") == 0 && g_value_get_boolean (value))
9681
      g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_default,
9682
			  GINT_TO_POINTER (TRUE));
9683
  else if (strcmp (name, "has-focus") == 0 && g_value_get_boolean (value))
9684
      g_object_set_qdata (G_OBJECT (buildable), quark_builder_has_focus,
9685
			  GINT_TO_POINTER (TRUE));
9686
  else
9687
    g_object_set_property (G_OBJECT (buildable), name, value);
9688
}
9689
9690
typedef struct {
9691
  gchar *action_name;
9692
  gchar *description;
9693
} AtkActionData;
9694
  
9695
typedef struct {
9696
  gchar *target;
9697
  gchar *type;
9698
} AtkRelationData;
9699
9700
static void
9701
free_action (AtkActionData *data, gpointer user_data)
9702
{
9703
  g_free (data->action_name);
9704
  g_free (data->description);
9705
  g_slice_free (AtkActionData, data);
9706
}
9707
9708
static void
9709
free_relation (AtkRelationData *data, gpointer user_data)
9710
{
9711
  g_free (data->target);
9712
  g_free (data->type);
9713
  g_slice_free (AtkRelationData, data);
9714
}
9715
9716
static void
9717
gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
9718
				      GtkBuilder   *builder)
9719
{
9720
  GSList *atk_relations;
9721
  
9722
  if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_default))
9723
    gtk_widget_grab_default (GTK_WIDGET (buildable));
9724
  if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_focus))
9725
    gtk_widget_grab_focus (GTK_WIDGET (buildable));
9726
9727
  atk_relations = g_object_get_qdata (G_OBJECT (buildable),
9728
				      quark_builder_atk_relations);
9729
  if (atk_relations)
9730
    {
9731
      AtkObject *accessible;
9732
      AtkRelationSet *relation_set;
9733
      GSList *l;
9734
      GObject *target;
9735
      AtkRelationType relation_type;
9736
      AtkObject *target_accessible;
9737
      
9738
      accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
9739
      relation_set = atk_object_ref_relation_set (accessible);
9740
9741
      for (l = atk_relations; l; l = l->next)
9742
	{
9743
	  AtkRelationData *relation = (AtkRelationData*)l->data;
9744
	  
9745
	  target = gtk_builder_get_object (builder, relation->target);
9746
	  if (!target)
9747
	    {
9748
	      g_warning ("Target object %s in <relation> does not exist",
9749
			 relation->target);
9750
	      continue;
9751
	    }
9752
	  target_accessible = gtk_widget_get_accessible (GTK_WIDGET (target));
9753
	  g_assert (target_accessible != NULL);
9754
	  
9755
	  relation_type = atk_relation_type_for_name (relation->type);
9756
	  if (relation_type == ATK_RELATION_NULL)
9757
	    {
9758
	      g_warning ("<relation> type %s not found",
9759
			 relation->type);
9760
	      continue;
9761
	    }
9762
	  atk_relation_set_add_relation_by_type (relation_set, relation_type,
9763
						 target_accessible);
9764
	}
9765
      g_object_unref (relation_set);
9766
9767
      g_slist_foreach (atk_relations, (GFunc)free_relation, NULL);
9768
      g_slist_free (atk_relations);
9769
      g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
9770
			  NULL);
9771
    }
9772
    
9773
}
9774
9775
typedef struct {
9776
  GSList *actions;
9777
  GSList *relations;
9778
} AccessibilitySubParserData;
9779
9780
static void
9781
accessibility_start_element (GMarkupParseContext *context,
9782
			     const gchar         *element_name,
9783
			     const gchar        **names,
9784
			     const gchar        **values,
9785
			     gpointer             user_data,
9786
			     GError             **error)
9787
{
9788
  AccessibilitySubParserData *data = (AccessibilitySubParserData*)user_data;
9789
  guint i;
9790
  gint line_number, char_number;
9791
9792
  if (strcmp (element_name, "relation") == 0)
9793
    {
9794
      gchar *target = NULL;
9795
      gchar *type = NULL;
9796
      AtkRelationData *relation;
9797
      
9798
      for (i = 0; names[i]; i++)
9799
	{
9800
	  if (strcmp (names[i], "target") == 0)
9801
	    target = g_strdup (values[i]);
9802
	  else if (strcmp (names[i], "type") == 0)
9803
	    type = g_strdup (values[i]);
9804
	  else
9805
	    {
9806
	      g_markup_parse_context_get_position (context,
9807
						   &line_number,
9808
						   &char_number);
9809
	      g_set_error (error,
9810
			   GTK_BUILDER_ERROR,
9811
			   GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
9812
			   "%s:%d:%d '%s' is not a valid attribute of <%s>",
9813
			   "<input>",
9814
			   line_number, char_number, names[i], "relation");
9815
	      g_free (target);
9816
	      g_free (type);
9817
	      return;
9818
	    }
9819
	}
9820
9821
      if (!target || !type)
9822
	{
9823
	  g_markup_parse_context_get_position (context,
9824
					       &line_number,
9825
					       &char_number);
9826
	  g_set_error (error,
9827
		       GTK_BUILDER_ERROR,
9828
		       GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
9829
		       "%s:%d:%d <%s> requires attribute \"%s\"",
9830
		       "<input>",
9831
		       line_number, char_number, "relation",
9832
		       type ? "target" : "type");
9833
	  g_free (target);
9834
	  g_free (type);
9835
	  return;
9836
	}
9837
9838
      relation = g_slice_new (AtkRelationData);
9839
      relation->target = target;
9840
      relation->type = type;
9841
      
9842
      data->relations = g_slist_prepend (data->relations, relation);
9843
    }
9844
  else if (strcmp (element_name, "action") == 0)
9845
    {
9846
      gchar *action_name = NULL;
9847
      gchar *description = NULL;
9848
      AtkActionData *action;
9849
      
9850
      for (i = 0; names[i]; i++)
9851
	{
9852
	  if (strcmp (names[i], "action_name") == 0)
9853
	    action_name = g_strdup (values[i]);
9854
	  else if (strcmp (names[i], "description") == 0)
9855
	    description = g_strdup (values[i]);
9856
	  else
9857
	    {
9858
	      g_markup_parse_context_get_position (context,
9859
						   &line_number,
9860
						   &char_number);
9861
	      g_set_error (error,
9862
			   GTK_BUILDER_ERROR,
9863
			   GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
9864
			   "%s:%d:%d '%s' is not a valid attribute of <%s>",
9865
			   "<input>",
9866
			   line_number, char_number, names[i], "action");
9867
	      g_free (action_name);
9868
	      g_free (description);
9869
	      return;
9870
	    }
9871
	}
9872
9873
      if (!action_name || !description)
9874
	{
9875
	  g_markup_parse_context_get_position (context,
9876
					       &line_number,
9877
					       &char_number);
9878
	  g_set_error (error,
9879
		       GTK_BUILDER_ERROR,
9880
		       GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
9881
		       "%s:%d:%d <%s> requires attribute \"%s\"",
9882
		       "<input>",
9883
		       line_number, char_number, "action",
9884
		       description ? "action_name" : "description");
9885
	  g_free (action_name);
9886
	  g_free (description);
9887
	  return;
9888
	}
9889
9890
      action = g_slice_new (AtkActionData);
9891
      action->action_name = action_name;
9892
      action->description = description;
9893
      
9894
      data->actions = g_slist_prepend (data->actions, action);
9895
    }
9896
  else if (strcmp (element_name, "accessibility") == 0)
9897
    ;
9898
  else
9899
    g_warning ("Unsupported tag for GtkWidget: %s\n", element_name);
9900
}
9901
9902
static const GMarkupParser accessibility_parser =
9903
  {
9904
    accessibility_start_element,
9905
  };
9906
9907
typedef struct {
9908
  GObject *object;
9909
  guint    key;
9910
  guint    modifiers;
9911
  gchar   *signal;
9912
} AccelGroupParserData;
9913
9914
static void
9915
accel_group_start_element (GMarkupParseContext *context,
9916
			   const gchar         *element_name,
9917
			   const gchar        **names,
9918
			   const gchar        **values,
9919
			   gpointer             user_data,
9920
			   GError             **error)
9921
{
9922
  gint i;
9923
  guint key = 0;
9924
  guint modifiers = 0;
9925
  gchar *signal = NULL;
9926
  AccelGroupParserData *parser_data = (AccelGroupParserData*)user_data;
9927
9928
  for (i = 0; names[i]; i++)
9929
    {
9930
      if (strcmp (names[i], "key") == 0)
9931
	key = gdk_keyval_from_name (values[i]);
9932
      else if (strcmp (names[i], "modifiers") == 0)
9933
	{
9934
	  if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE,
9935
					       values[i],
9936
					       &modifiers,
9937
					       error))
9938
	      return;
9939
	}
9940
      else if (strcmp (names[i], "signal") == 0)
9941
	signal = g_strdup (values[i]);
9942
    }
9943
9944
  if (key == 0 || signal == NULL)
9945
    {
9946
      g_warning ("<accelerator> requires key and signal attributes");
9947
      return;
9948
    }
9949
  parser_data->key = key;
9950
  parser_data->modifiers = modifiers;
9951
  parser_data->signal = signal;
9952
}
9953
9954
static const GMarkupParser accel_group_parser =
9955
  {
9956
    accel_group_start_element,
9957
  };
9958
9959
static gboolean
9960
gtk_widget_buildable_custom_tag_start (GtkBuildable     *buildable,
9961
				       GtkBuilder       *builder,
9962
				       GObject          *child,
9963
				       const gchar      *tagname,
9964
				       GMarkupParser    *parser,
9965
				       gpointer         *data)
9966
{
9967
  g_assert (buildable);
9968
9969
  if (strcmp (tagname, "accelerator") == 0)
9970
    {
9971
      AccelGroupParserData *parser_data;
9972
9973
      parser_data = g_slice_new0 (AccelGroupParserData);
9974
      parser_data->object = g_object_ref (buildable);
9975
      *parser = accel_group_parser;
9976
      *data = parser_data;
9977
      return TRUE;
9978
    }
9979
  if (strcmp (tagname, "accessibility") == 0)
9980
    {
9981
      AccessibilitySubParserData *parser_data;
9982
9983
      parser_data = g_slice_new0 (AccessibilitySubParserData);
9984
      *parser = accessibility_parser;
9985
      *data = parser_data;
9986
      return TRUE;
9987
    }
9988
  return FALSE;
9989
}
9990
9991
static void
9992
gtk_widget_buildable_custom_finished (GtkBuildable *buildable,
9993
				      GtkBuilder   *builder,
9994
				      GObject      *child,
9995
				      const gchar  *tagname,
9996
				      gpointer      user_data)
9997
{
9998
  AccelGroupParserData *accel_data;
9999
  AccessibilitySubParserData *a11y_data;
10000
  GtkWidget *toplevel;
10001
  GSList *accel_groups;
10002
  GtkAccelGroup *accel_group;
10003
10004
  if (strcmp (tagname, "accelerator") == 0)
10005
    {
10006
      accel_data = (AccelGroupParserData*)user_data;
10007
      g_assert (accel_data->object);
10008
10009
      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (accel_data->object));
10010
      accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
10011
      if (g_slist_length (accel_groups) == 0)
10012
	{
10013
	  accel_group = gtk_accel_group_new ();
10014
	  gtk_window_add_accel_group (GTK_WINDOW (toplevel), accel_group);
10015
	}
10016
      else
10017
	{
10018
	  g_assert (g_slist_length (accel_groups) == 1);
10019
	  accel_group = g_slist_nth_data (accel_groups, 0);
10020
	}
10021
      gtk_widget_add_accelerator (GTK_WIDGET (accel_data->object),
10022
				  accel_data->signal,
10023
				  accel_group,
10024
				  accel_data->key,
10025
				  accel_data->modifiers,
10026
				  GTK_ACCEL_VISIBLE);
10027
      g_object_unref (accel_data->object);
10028
      g_free (accel_data->signal);
10029
      g_slice_free (AccelGroupParserData, accel_data);
10030
    }
10031
  else if (strcmp (tagname, "accessibility") == 0)
10032
    {
10033
      a11y_data = (AccessibilitySubParserData*)user_data;
10034
10035
      if (a11y_data->actions)
10036
	{
10037
	  AtkObject *accessible;
10038
	  AtkAction *action;
10039
	  gint i, n_actions;
10040
	  GSList *l;
10041
	  
10042
	  accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
10043
	  
10044
	  action = ATK_ACTION (accessible);
10045
	  n_actions = atk_action_get_n_actions (action);    
10046
	  
10047
	  for (l = a11y_data->actions; l; l = l->next)
10048
	    {
10049
	      AtkActionData *action_data = (AtkActionData*)l->data;
10050
	      
10051
	      for (i = 0; i < n_actions; i++)
10052
		if (strcmp (atk_action_get_name (action, i),
10053
			    action_data->action_name) == 0)
10054
		  break;
10055
10056
	      if (i < n_actions)
10057
		atk_action_set_description (action, i,
10058
					    action_data->description);
10059
	    }
10060
	  
10061
	  g_slist_foreach (a11y_data->actions, (GFunc)free_action, NULL);
10062
	  g_slist_free (a11y_data->actions);
10063
	}
10064
10065
      if (a11y_data->relations)
10066
	g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
10067
			    a11y_data->relations);
10068
      
10069
      g_slice_free (AccessibilitySubParserData, a11y_data);
10070
      
10071
    }
10072
}
10073
10074
10075
/**
10076
 * gtk_widget_get_clipboard:
10077
 * @widget: a #GtkWidget
10078
 * @selection: a #GdkAtom which identifies the clipboard
10079
 *             to use. %GDK_SELECTION_CLIPBOARD gives the
10080
 *             default clipboard. Another common value
10081
 *             is %GDK_SELECTION_PRIMARY, which gives
10082
 *             the primary X selection. 
10083
 * 
10084
 * Returns the clipboard object for the given selection to
10085
 * be used with @widget. @widget must have a #GdkDisplay
10086
 * associated with it, so must be attached to a toplevel
10087
 * window.
10088
 * 
10089
 * Return value: the appropriate clipboard object. If no
10090
 *             clipboard already exists, a new one will
10091
 *             be created. Once a clipboard object has
10092
 *             been created, it is persistent for all time.
10093
 *
10094
 * Since: 2.2
10095
 **/
10096
GtkClipboard *
10097
gtk_widget_get_clipboard (GtkWidget *widget, GdkAtom selection)
10098
{
10099
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10100
  g_return_val_if_fail (gtk_widget_has_screen (widget), NULL);
10101
  
10102
  return gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
10103
					selection);
10104
}
10105
10106
/**
10107
 * gtk_widget_list_mnemonic_labels:
10108
 * @widget: a #GtkWidget
10109
 * 
10110
 * Returns a newly allocated list of the widgets, normally labels, for 
10111
 * which this widget is a the target of a mnemonic (see for example, 
10112
 * gtk_label_set_mnemonic_widget()).
10113
10114
 * The widgets in the list are not individually referenced. If you
10115
 * want to iterate through the list and perform actions involving
10116
 * callbacks that might destroy the widgets, you
10117
 * <emphasis>must</emphasis> call <literal>g_list_foreach (result,
10118
 * (GFunc)g_object_ref, NULL)</literal> first, and then unref all the
10119
 * widgets afterwards.
10120
10121
 * Return value: the list of mnemonic labels; free this list
10122
 *  with g_list_free() when you are done with it.
10123
 *
10124
 * Since: 2.4
10125
 **/
10126
GList *
10127
gtk_widget_list_mnemonic_labels (GtkWidget *widget)
10128
{
10129
  GList *list = NULL;
10130
  GSList *l;
10131
  
10132
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10133
10134
  for (l = g_object_get_qdata (G_OBJECT (widget), quark_mnemonic_labels); l; l = l->next)
10135
    list = g_list_prepend (list, l->data);
10136
10137
  return list;
10138
}
10139
10140
/**
10141
 * gtk_widget_add_mnemonic_label:
10142
 * @widget: a #GtkWidget
10143
 * @label: a #GtkWidget that acts as a mnemonic label for @widget
10144
 * 
10145
 * Adds a widget to the list of mnemonic labels for
10146
 * this widget. (See gtk_widget_list_mnemonic_labels()). Note the
10147
 * list of mnemonic labels for the widget is cleared when the
10148
 * widget is destroyed, so the caller must make sure to update
10149
 * its internal state at this point as well, by using a connection
10150
 * to the #GtkWidget::destroy signal or a weak notifier.
10151
 *
10152
 * Since: 2.4
10153
 **/
10154
void
10155
gtk_widget_add_mnemonic_label (GtkWidget *widget,
10156
                               GtkWidget *label)
10157
{
10158
  GSList *old_list, *new_list;
10159
10160
  g_return_if_fail (GTK_IS_WIDGET (widget));
10161
  g_return_if_fail (GTK_IS_WIDGET (label));
10162
10163
  old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
10164
  new_list = g_slist_prepend (old_list, label);
10165
  
10166
  g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
10167
			   new_list, (GDestroyNotify) g_slist_free);
10168
}
10169
10170
/**
10171
 * gtk_widget_remove_mnemonic_label:
10172
 * @widget: a #GtkWidget
10173
 * @label: a #GtkWidget that was previously set as a mnemnic label for
10174
 *         @widget with gtk_widget_add_mnemonic_label().
10175
 * 
10176
 * Removes a widget from the list of mnemonic labels for
10177
 * this widget. (See gtk_widget_list_mnemonic_labels()). The widget
10178
 * must have previously been added to the list with
10179
 * gtk_widget_add_mnemonic_label().
10180
 *
10181
 * Since: 2.4
10182
 **/
10183
void
10184
gtk_widget_remove_mnemonic_label (GtkWidget *widget,
10185
                                  GtkWidget *label)
10186
{
10187
  GSList *old_list, *new_list;
10188
10189
  g_return_if_fail (GTK_IS_WIDGET (widget));
10190
  g_return_if_fail (GTK_IS_WIDGET (label));
10191
10192
  old_list = g_object_steal_qdata (G_OBJECT (widget), quark_mnemonic_labels);
10193
  new_list = g_slist_remove (old_list, label);
10194
10195
  if (new_list)
10196
    g_object_set_qdata_full (G_OBJECT (widget), quark_mnemonic_labels,
10197
			     new_list, (GDestroyNotify) g_slist_free);
10198
}
10199
10200
/**
10201
 * gtk_widget_get_no_show_all:
10202
 * @widget: a #GtkWidget
10203
 * 
10204
 * Returns the current value of the GtkWidget:no-show-all property, 
10205
 * which determines whether calls to gtk_widget_show_all() and 
10206
 * gtk_widget_hide_all() will affect this widget. 
10207
 * 
10208
 * Return value: the current value of the "no-show-all" property.
10209
 *
10210
 * Since: 2.4
10211
 **/
10212
gboolean
10213
gtk_widget_get_no_show_all (GtkWidget *widget)
10214
{
10215
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
10216
  
10217
  return (GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0;
10218
}
10219
10220
/**
10221
 * gtk_widget_set_no_show_all:
10222
 * @widget: a #GtkWidget
10223
 * @no_show_all: the new value for the "no-show-all" property
10224
 * 
10225
 * Sets the #GtkWidget:no-show-all property, which determines whether 
10226
 * calls to gtk_widget_show_all() and gtk_widget_hide_all() will affect 
10227
 * this widget. 
10228
 *
10229
 * This is mostly for use in constructing widget hierarchies with externally
10230
 * controlled visibility, see #GtkUIManager.
10231
 * 
10232
 * Since: 2.4
10233
 **/
10234
void
10235
gtk_widget_set_no_show_all (GtkWidget *widget,
10236
			    gboolean   no_show_all)
10237
{
10238
  g_return_if_fail (GTK_IS_WIDGET (widget));
10239
10240
  no_show_all = (no_show_all != FALSE);
10241
10242
  if (no_show_all == ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0))
10243
    return;
10244
10245
  if (no_show_all)
10246
    GTK_WIDGET_SET_FLAGS (widget, GTK_NO_SHOW_ALL);
10247
  else
10248
    GTK_WIDGET_UNSET_FLAGS (widget, GTK_NO_SHOW_ALL);
10249
  
10250
  g_object_notify (G_OBJECT (widget), "no-show-all");
10251
}
10252
10253
10254
static void
10255
gtk_widget_real_set_has_tooltip (GtkWidget *widget,
10256
			         gboolean   has_tooltip,
10257
			         gboolean   force)
10258
{
10259
  gboolean priv_has_tooltip;
10260
10261
  priv_has_tooltip = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (widget),
10262
				       quark_has_tooltip));
10263
10264
  if (priv_has_tooltip != has_tooltip || force)
10265
    {
10266
      priv_has_tooltip = has_tooltip;
10267
10268
      if (priv_has_tooltip)
10269
        {
10270
	  if (GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_NO_WINDOW (widget))
10271
	    gdk_window_set_events (widget->window,
10272
				   gdk_window_get_events (widget->window) |
10273
				   GDK_LEAVE_NOTIFY_MASK |
10274
				   GDK_POINTER_MOTION_MASK |
10275
				   GDK_POINTER_MOTION_HINT_MASK);
10276
10277
	  if (!GTK_WIDGET_NO_WINDOW (widget))
10278
	      gtk_widget_add_events (widget,
10279
				     GDK_LEAVE_NOTIFY_MASK |
10280
				     GDK_POINTER_MOTION_MASK |
10281
				     GDK_POINTER_MOTION_HINT_MASK);
10282
	}
10283
10284
      g_object_set_qdata (G_OBJECT (widget), quark_has_tooltip,
10285
			  GUINT_TO_POINTER (priv_has_tooltip));
10286
    }
10287
}
10288
10289
/**
10290
 * gtk_widget_set_tooltip_window:
10291
 * @widget: a #GtkWidget
10292
 * @custom_window: a #GtkWindow, or %NULL
10293
 *
10294
 * Replaces the default, usually yellow, window used for displaying
10295
 * tooltips with @custom_window. GTK+ will take care of showing and
10296
 * hiding @custom_window at the right moment, to behave likewise as
10297
 * the default tooltip window. If @custom_window is %NULL, the default
10298
 * tooltip window will be used.
10299
 *
10300
 * Since: 2.12
10301
 */
10302
void
10303
gtk_widget_set_tooltip_window (GtkWidget *widget,
10304
			       GtkWindow *custom_window)
10305
{
10306
  gboolean tmp;
10307
  gchar *tooltip_markup;
10308
  GtkWindow *tooltip_window;
10309
10310
  g_return_if_fail (GTK_IS_WIDGET (widget));
10311
  if (custom_window)
10312
    g_return_if_fail (GTK_IS_WINDOW (custom_window));
10313
10314
  tooltip_window = g_object_get_qdata (G_OBJECT (widget), quark_tooltip_window);
10315
  tooltip_markup = g_object_get_qdata (G_OBJECT (widget), quark_tooltip_markup);
10316
10317
  if (custom_window)
10318
    g_object_ref (custom_window);
10319
10320
  tooltip_window = custom_window;
10321
  g_object_set_qdata_full (G_OBJECT (widget), quark_tooltip_window,
10322
			   tooltip_window, g_object_unref);
10323
10324
  tmp = (tooltip_window != NULL || tooltip_markup != NULL);
10325
  gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
10326
10327
  if (tmp)
10328
    gtk_widget_trigger_tooltip_query (widget);
10329
}
10330
10331
/**
10332
 * gtk_widget_get_tooltip_window:
10333
 * @widget: a #GtkWidget
10334
 *
10335
 * Returns the #GtkWindow of the current tooltip. This can be the
10336
 * GtkWindow created by default, or the custom tooltip window set
10337
 * using gtk_widget_set_tooltip_window().
10338
 *
10339
 * Return value: The #GtkWindow of the current tooltip.
10340
 *
10341
 * Since: 2.12
10342
 */
10343
GtkWindow *
10344
gtk_widget_get_tooltip_window (GtkWidget *widget)
10345
{
10346
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10347
10348
  return g_object_get_qdata (G_OBJECT (widget), quark_tooltip_window);
10349
}
10350
10351
/**
10352
 * gtk_widget_trigger_tooltip_query:
10353
 * @widget: a #GtkWidget
10354
 *
10355
 * Triggers a tooltip query on the display where the toplevel of @widget
10356
 * is located. See gtk_tooltip_trigger_tooltip_query() for more
10357
 * information.
10358
 *
10359
 * Since: 2.12
10360
 */
10361
void
10362
gtk_widget_trigger_tooltip_query (GtkWidget *widget)
10363
{
10364
  gtk_tooltip_trigger_tooltip_query (gtk_widget_get_display (widget));
10365
}
10366
10367
/**
10368
 * gtk_widget_set_tooltip_text:
10369
 * @widget: a #GtkWidget
10370
 * @text: the contents of the tooltip for @widget
10371
 *
10372
 * Sets @text as the contents of the tooltip. This function will take
10373
 * care of setting GtkWidget:has-tooltip to %TRUE and of the default
10374
 * handler for the GtkWidget::query-tooltip signal.
10375
 *
10376
 * See also the GtkWidget:tooltip-text property and gtk_tooltip_set_text().
10377
 *
10378
 * Since: 2.12
10379
 */
10380
void
10381
gtk_widget_set_tooltip_text (GtkWidget   *widget,
10382
                             const gchar *text)
10383
{
10384
  g_return_if_fail (GTK_IS_WIDGET (widget));
10385
10386
  g_object_set (G_OBJECT (widget), "tooltip-text", text, NULL);
10387
}
10388
10389
/**
10390
 * gtk_widget_get_tooltip_text:
10391
 * @widget: a #GtkWidget
10392
 *
10393
 * Gets the contents of the tooltip for @widget.
10394
 *
10395
 * Return value: the tooltip text, or %NULL. You should free the
10396
 *   returned string with g_free() when done.
10397
 *
10398
 * Since: 2.12
10399
 */
10400
gchar *
10401
gtk_widget_get_tooltip_text (GtkWidget *widget)
10402
{
10403
  gchar *text = NULL;
10404
10405
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10406
10407
  g_object_get (G_OBJECT (widget), "tooltip-text", &text, NULL);
10408
10409
  return text;
10410
}
10411
10412
/**
10413
 * gtk_widget_set_tooltip_markup:
10414
 * @widget: a #GtkWidget
10415
 * @markup: the contents of the tooltip for @widget, or %NULL
10416
 *
10417
 * Sets @markup as the contents of the tooltip, which is marked up with
10418
 *  the <link linkend="PangoMarkupFormat">Pango text markup language</link>.
10419
 *
10420
 * This function will take care of setting GtkWidget:has-tooltip to %TRUE
10421
 * and of the default handler for the GtkWidget::query-tooltip signal.
10422
 *
10423
 * See also the GtkWidget:tooltip-markup property and
10424
 * gtk_tooltip_set_markup().
10425
 *
10426
 * Since: 2.12
10427
 */
10428
void
10429
gtk_widget_set_tooltip_markup (GtkWidget   *widget,
10430
                               const gchar *markup)
10431
{
10432
  g_return_if_fail (GTK_IS_WIDGET (widget));
10433
10434
  g_object_set (G_OBJECT (widget), "tooltip-markup", markup, NULL);
10435
}
10436
10437
/**
10438
 * gtk_widget_get_tooltip_markup:
10439
 * @widget: a #GtkWidget
10440
 *
10441
 * Gets the contents of the tooltip for @widget.
10442
 *
10443
 * Return value: the tooltip text, or %NULL. You should free the
10444
 *   returned string with g_free() when done.
10445
 *
10446
 * Since: 2.12
10447
 */
10448
gchar *
10449
gtk_widget_get_tooltip_markup (GtkWidget *widget)
10450
{
10451
  gchar *text = NULL;
10452
10453
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10454
10455
  g_object_get (G_OBJECT (widget), "tooltip-markup", &text, NULL);
10456
10457
  return text;
10458
}
10459
10460
/**
10461
 * gtk_widget_set_has_tooltip:
10462
 * @widget: a #GtkWidget
10463
 * @has_tooltip: whether or not @widget has a tooltip.
10464
 *
10465
 * Sets the has-tooltip property on @widget to @has_tooltip.  See
10466
 * GtkWidget:has-tooltip for more information.
10467
 *
10468
 * Since: 2.12
10469
 */
10470
void
10471
gtk_widget_set_has_tooltip (GtkWidget *widget,
10472
			    gboolean   has_tooltip)
10473
{
10474
  g_return_if_fail (GTK_IS_WIDGET (widget));
10475
10476
  g_object_set (G_OBJECT (widget), "has-tooltip", has_tooltip, NULL);
10477
}
10478
10479
/**
10480
 * gtk_widget_get_has_tooltip:
10481
 * @widget: a #GtkWidget
10482
 *
10483
 * Returns the current value of the has-tooltip property.  See
10484
 * GtkWidget:has-tooltip for more information.
10485
 *
10486
 * Return value: current value of has-tooltip on @widget.
10487
 *
10488
 * Since: 2.12
10489
 */
10490
gboolean
10491
gtk_widget_get_has_tooltip (GtkWidget *widget)
10492
{
10493
  gboolean has_tooltip = FALSE;
10494
10495
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
10496
10497
  g_object_get (G_OBJECT (widget), "has-tooltip", &has_tooltip, NULL);
10498
10499
  return has_tooltip;
10500
}
10501
10502
/**
10503
 * gtk_widget_get_window:
10504
 * @widget: a #GtkWidget
10505
 *
10506
 * Returns the widget's window if it is realized, %NULL otherwise
10507
 *
10508
 * Return value: @widget's window.
10509
 *
10510
 * Since: 2.14
10511
 */
10512
GdkWindow*
10513
gtk_widget_get_window (GtkWidget *widget)
10514
{
10515
  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
10516
10517
  return widget->window;
10518
}
10519
10520
#ifdef MAEMO_CHANGES
10521
void gtk_widget_set_hildon_focus_handling( GtkWidget *widget, gboolean hildon_like )
10522
{
10523
}
10524
10525
gboolean gtk_widget_get_hildon_focus_handling( GtkWidget *widget )
10526
{
10527
  return FALSE;
10528
}
10529
10530
10531
/* -- Tap and hold implementation -- */
10532
10533
static TahData*
10534
gtk_widget_peek_tah_data (GtkWidget *widget)
10535
{
10536
  TahData *td = g_object_get_data (G_OBJECT (widget), "MaemoGtkWidget-tap-and-hold");
10537
  return td;
10538
}
10539
10540
static void
10541
tap_and_hold_stop_animation (TahData *td)
10542
{
10543
#ifdef TAP_AND_HOLD_ANIMATION
10544
  if (td->tah_on_window)
10545
    gdk_window_set_cursor (td->tah_on_window, NULL);
10546
  td->tah_on_window = NULL;
10547
10548
  if (td->anim)
10549
    g_object_unref (td->anim);
10550
  td->anim = NULL;
10551
10552
  if (td->iter)
10553
    g_object_unref (td->iter);
10554
  td->iter = NULL;
10555
#endif
10556
}
10557
10558
static void
10559
tap_and_hold_free_data (gpointer data)
10560
{
10561
  TahData *td = data;
10562
  if (td)
10563
    {
10564
      if (td->timer_id)
10565
	g_source_remove (td->timer_id);
10566
      td->timer_id = 0;
10567
10568
      if (GTK_IS_MENU (td->menu))
10569
	g_object_unref (td->menu);
10570
      td->menu = NULL;
10571
10572
      tap_and_hold_stop_animation (td);
10573
10574
      g_free (td);
10575
    }
10576
}
10577
10578
static void
10579
gtk_widget_set_tah_data (GtkWidget *widget, TahData *td)
10580
{
10581
  g_object_set_data_full (G_OBJECT (widget), "MaemoGtkWidget-tap-and-hold",
10582
			  td, tap_and_hold_free_data);
10583
}
10584
10585
static TahData*
10586
gtk_widget_get_tah_data (GtkWidget *widget)
10587
{
10588
  TahData *td = gtk_widget_peek_tah_data (widget);
10589
  if (!td)
10590
    {
10591
      td = g_new0 (TahData, 1);
10592
      td->interval = TAP_AND_HOLD_TIMER_INTERVAL;
10593
      gtk_widget_set_tah_data (widget, td);
10594
    }
10595
  return td;
10596
}
10597
10598
static void
10599
tap_and_hold_remove_timer (GtkWidget *widget)
10600
{
10601
  TahData *td = gtk_widget_peek_tah_data (widget);
10602
  if (td)
10603
    {
10604
      if (td->timer_id)
10605
	{
10606
	  g_source_remove (td->timer_id);
10607
	  td->timer_id = 0;
10608
	}
10609
10610
      td->x = td->y = td->timer_counter = 0;
10611
      tap_and_hold_stop_animation (td);
10612
    }
10613
}
10614
10615
#ifdef TAP_AND_HOLD_ANIMATION
10616
static GdkPixbufAnimation *
10617
tap_and_hold_load_animation_for_screen (GdkScreen *screen)
10618
{
10619
  GtkIconTheme *theme;
10620
  GtkIconInfo *info;
10621
  const char *filename = NULL;
10622
  GdkPixbufAnimation *anim = NULL;
10623
  GError *error = NULL;
10624
10625
  theme = gtk_icon_theme_get_for_screen (screen);
10626
10627
  info = gtk_icon_theme_lookup_icon (theme, "qgn_indi_tap_hold_a",
10628
				     GTK_ICON_SIZE_BUTTON,
10629
				     GTK_ICON_LOOKUP_NO_SVG);
10630
  if (info)
10631
    filename = gtk_icon_info_get_filename (info);
10632
  if (!info || !filename)
10633
    {
10634
      g_warning ("Unable to find tap and hold icon filename");
10635
      goto out;
10636
    }
10637
10638
  anim = gdk_pixbuf_animation_new_from_file (filename, &error);
10639
  if (!anim)
10640
    {
10641
      g_warning ("Unable to load tap and hold animation: %s", error->message);
10642
      goto out;
10643
    }
10644
10645
out:
10646
  if (info)
10647
    gtk_icon_info_free (info);
10648
  if (error)
10649
    g_error_free (error);
10650
10651
  return anim;
10652
}
10653
#endif
10654
10655
static void
10656
tap_and_hold_init_animation (TahData *td)
10657
{
10658
#ifdef TAP_AND_HOLD_ANIMATION
10659
  if (!td->anim)
10660
    td->anim = tap_and_hold_load_animation_for_screen (gdk_drawable_get_screen (td->tah_on_window));
10661
10662
  if (td->anim)
10663
    {
10664
      if (td->iter)
10665
	g_object_unref (td->iter);
10666
      td->iter = gdk_pixbuf_animation_get_iter (td->anim, NULL);
10667
10668
      td->interval = gdk_pixbuf_animation_iter_get_delay_time (td->iter);
10669
    }
10670
#endif
10671
}
10672
10673
static gboolean
10674
tap_and_hold_animation_timeout (GtkWidget *widget)
10675
{
10676
#ifdef TAP_AND_HOLD_ANIMATION
10677
  TahData *td = gtk_widget_peek_tah_data (widget);
10678
10679
  if (!td || !GDK_IS_WINDOW (td->tah_on_window))
10680
    {
10681
      tap_and_hold_remove_timer (widget);
10682
      return FALSE;
10683
    }
10684
10685
  if (td->anim)
10686
    {
10687
      guint new_interval = 0;
10688
      GTimeVal time;
10689
      GdkScreen *screen;
10690
      GdkPixbuf *pic;
10691
      GdkCursor *cursor;
10692
      const gchar *x_hot, *y_hot;
10693
      gint x, y;
10694
10695
      g_get_current_time (&time);
10696
      screen = gdk_screen_get_default ();
10697
      pic = gdk_pixbuf_animation_iter_get_pixbuf (td->iter);
10698
10699
      pic = gdk_pixbuf_copy (pic);
10700
10701
      if (!GDK_IS_PIXBUF (pic))
10702
        return TRUE;
10703
10704
      x_hot = gdk_pixbuf_get_option (pic, "x_hot");
10705
      y_hot = gdk_pixbuf_get_option (pic, "y_hot");
10706
      x = (x_hot) ? atoi(x_hot) : gdk_pixbuf_get_width(pic) / 2;
10707
      y = (y_hot) ? atoi(y_hot) : gdk_pixbuf_get_height(pic) / 2;
10708
10709
      cursor = gdk_cursor_new_from_pixbuf (gdk_display_get_default (), pic,
10710
                                           x, y);
10711
      g_object_unref (pic);
10712
10713
      if (!cursor)
10714
        return TRUE;
10715
10716
      gdk_window_set_cursor (td->tah_on_window, cursor);
10717
      gdk_cursor_unref (cursor);
10718
10719
      gdk_pixbuf_animation_iter_advance (td->iter, &time);
10720
10721
      new_interval = gdk_pixbuf_animation_iter_get_delay_time (td->iter);
10722
10723
      if (new_interval != td->interval && td->timer_counter)
10724
	{
10725
	  td->interval = new_interval;
10726
	  td->timer_id = g_timeout_add (td->interval,
10727
					(GSourceFunc)gtk_widget_tap_and_hold_timeout, widget);
10728
	  return FALSE;
10729
	}
10730
    }
10731
#endif
10732
  return TRUE;
10733
}
10734
10735
/**
10736
 * gtk_widget_tap_and_hold_menu_position_top:
10737
 * @menu: a #GtkMenu
10738
 * @x: x cordinate to be returned
10739
 * @y: y cordinate to be returned
10740
 * @push_in: If going off screen, push it pack on the screen
10741
 * @widget: a #GtkWidget
10742
 *
10743
 * Pre-made menu positioning function.
10744
 * It positiones the @menu over the @widget.
10745
 *
10746
 * Since: maemo 1.0
10747
 * Stability: Unstable
10748
 **/
10749
void
10750
gtk_widget_tap_and_hold_menu_position_top (GtkWidget *menu,
10751
					   gint      *x,
10752
					   gint      *y,
10753
					   gboolean  *push_in,
10754
					   GtkWidget *widget)
10755
{
10756
  /*
10757
   * This function positiones the menu above widgets.
10758
   * This is a modified version of the position function
10759
   * gtk_combo_box_position_over.
10760
   */
10761
  GtkWidget *topw;
10762
  GtkRequisition requisition;
10763
  gint screen_width = 0;
10764
  gint menu_xpos = 0;
10765
  gint menu_ypos = 0;
10766
  gint w_xpos = 0, w_ypos = 0;
10767
  gtk_widget_size_request (menu, &requisition);
10768
10769
  topw = gtk_widget_get_toplevel (widget);
10770
  gdk_window_get_origin (topw->window, &w_xpos, &w_ypos);
10771
10772
  menu_xpos += widget->allocation.x + w_xpos;
10773
  menu_ypos += widget->allocation.y + w_ypos - requisition.height;
10774
10775
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
10776
    menu_xpos = menu_xpos + widget->allocation.width - requisition.width;
10777
10778
  screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget));
10779
10780
  if (menu_xpos < w_xpos)
10781
    menu_xpos = w_xpos;
10782
  else if ((menu_xpos + requisition.width) > screen_width)
10783
    menu_xpos -= ((menu_xpos + requisition.width) - screen_width);
10784
  if (menu_ypos < w_ypos)
10785
    menu_ypos = w_ypos;
10786
10787
  *x = menu_xpos;
10788
  *y = menu_ypos;
10789
  *push_in = TRUE;
10790
}
10791
10792
/**
10793
 * gtk_widget_tap_and_hold_setup:
10794
 * @widget : a #GtkWidget
10795
 * @menu : a #GtkMenu or %NULL
10796
 * @func : a #GtkMenuPositionFunc or %NULL
10797
 * @flags : a #GtkWidgetTapAndHoldFlags
10798
 *
10799
 * Setups the tap and hold functionality to the @widget.
10800
 * The @menu is shown when the functionality is activated.
10801
 * If the @menu is wanted to be positioned in a different way than the
10802
 * gtk+ default, the menuposition @func can be passed as a third parameter.
10803
 * Fourth parameter, @flags is deprecated and has no effect.
10804
 *
10805
 * Since: maemo 1.0
10806
 * Stability: Unstable
10807
 */
10808
void
10809
gtk_widget_tap_and_hold_setup (GtkWidget                *widget,
10810
			       GtkWidget                *menu,
10811
			       GtkCallback               func,
10812
			       GtkWidgetTapAndHoldFlags  flags)
10813
{
10814
  g_return_if_fail (GTK_IS_WIDGET (widget));
10815
  g_return_if_fail (menu == NULL || GTK_IS_MENU (menu));
10816
10817
  g_signal_emit (widget, widget_signals[TAP_AND_HOLD_SETUP], 0, menu, func,
10818
		 flags);
10819
}
10820
10821
static void
10822
gtk_widget_real_tap_and_hold_setup (GtkWidget                *widget,
10823
				    GtkWidget                *menu,
10824
				    GtkCallback               func,
10825
				    GtkWidgetTapAndHoldFlags  flags)
10826
{
10827
  TahData *td;
10828
10829
  g_return_if_fail (GTK_IS_WIDGET (widget));
10830
  g_return_if_fail (menu == NULL || GTK_IS_MENU (menu));
10831
10832
  td = gtk_widget_get_tah_data (widget);
10833
  if (td->signals_connected)
10834
    return;
10835
10836
  if (menu != NULL)
10837
    {
10838
      g_object_ref_sink (menu);
10839
10840
      if (gtk_menu_get_attach_widget (GTK_MENU (menu)) == NULL)
10841
	gtk_menu_attach_to_widget (GTK_MENU (menu), widget, NULL);
10842
    }
10843
10844
  td->menu = menu;
10845
  td->func = (GtkMenuPositionFunc)func;
10846
  td->signals_connected = TRUE;
10847
  td->timer_counter = 0;
10848
10849
  g_signal_connect (widget, "button-press-event",
10850
		    G_CALLBACK (gtk_widget_tap_and_hold_button_press), td);
10851
  g_signal_connect (widget, "button-release-event",
10852
		    G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td);
10853
  g_signal_connect (widget, "leave-notify-event",
10854
		    G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td);
10855
  g_signal_connect (widget, "drag-begin",
10856
		    G_CALLBACK (gtk_widget_tap_and_hold_event_stop), td);
10857
}
10858
10859
static void
10860
gtk_widget_real_tap_and_hold (GtkWidget *widget)
10861
{
10862
  TahData *td = gtk_widget_peek_tah_data (widget);
10863
  if (td && GTK_IS_MENU (td->menu))
10864
    gtk_menu_popup (GTK_MENU (td->menu), NULL, NULL,
10865
		    (GtkMenuPositionFunc)td->func,
10866
		    widget, 1, gdk_x11_get_server_time (widget->window));
10867
}
10868
10869
static gboolean
10870
gtk_widget_tap_and_hold_timeout (GtkWidget *widget)
10871
{
10872
  TahData *td = gtk_widget_peek_tah_data (widget);
10873
  gboolean result;
10874
  gint x = 0, y = 0;
10875
10876
  GDK_THREADS_ENTER ();
10877
10878
  if (!td || !GDK_IS_WINDOW (td->tah_on_window))
10879
    {
10880
      tap_and_hold_remove_timer (widget);
10881
10882
      GDK_THREADS_LEAVE ();
10883
      return FALSE;
10884
    }
10885
10886
  /* A small timeout before starting the tap and hold */
10887
  if (td->timer_counter == TAP_AND_HOLD_TIMER_COUNTER)
10888
    {
10889
      td->timer_counter--;
10890
10891
      GDK_THREADS_LEAVE ();
10892
      return TRUE;
10893
    }
10894
10895
  result = tap_and_hold_animation_timeout (widget);
10896
10897
  if (td->timer_counter)
10898
    td->timer_counter--;
10899
  else
10900
    td->timer_id = 0;
10901
10902
  gdk_display_get_pointer (gdk_drawable_get_display (td->tah_on_window),
10903
                           NULL, &x, &y, NULL);
10904
10905
  /* Did we dragged too far from the start point */
10906
  if (gtk_drag_check_threshold (widget, td->x, td->y, x, y))
10907
    {
10908
      tap_and_hold_remove_timer (widget);
10909
10910
      GDK_THREADS_LEAVE ();
10911
      return FALSE;
10912
    }
10913
10914
  /* Was that the last cycle -> tah starts */
10915
  if (!td->timer_id)
10916
    {
10917
      tap_and_hold_remove_timer (widget);
10918
10919
      _gtk_menu_push_context_menu_behavior ();
10920
10921
      g_signal_emit (widget, widget_signals[TAP_AND_HOLD], 0);
10922
10923
      _gtk_menu_pop_context_menu_behavior ();
10924
10925
      GDK_THREADS_LEAVE ();
10926
      return FALSE;
10927
    }
10928
10929
  GDK_THREADS_LEAVE ();
10930
  return result;
10931
}
10932
10933
static gboolean
10934
gtk_widget_tap_and_hold_query_accumulator (GSignalInvocationHint *ihint,
10935
                                           GValue                *return_accu,
10936
                                           const GValue          *handler_return,
10937
                                           gpointer               dummy)
10938
{
10939
  gboolean tap_and_hold_not_allowed;
10940
10941
  /* The semantics of the tap-and-hold-query return value differs from
10942
   * the normal event signal handlers.
10943
   */
10944
10945
  tap_and_hold_not_allowed = g_value_get_boolean (handler_return);
10946
  g_value_set_boolean (return_accu, tap_and_hold_not_allowed);
10947
10948
  /* Now that a single handler has run, we stop emission. */
10949
  return FALSE;
10950
}
10951
10952
static gboolean
10953
gtk_widget_real_tap_and_hold_query (GtkWidget *widget,
10954
				    GdkEvent  *event)
10955
{
10956
  return FALSE;
10957
}
10958
10959
static gboolean
10960
gtk_widget_tap_and_hold_query (GtkWidget *widget,
10961
			       GdkEvent  *event)
10962
{
10963
  gboolean return_value = FALSE;
10964
10965
  g_signal_emit (G_OBJECT (widget), widget_signals[TAP_AND_HOLD_QUERY],
10966
		 0, event, &return_value);
10967
10968
  return return_value;
10969
}
10970
10971
static gboolean
10972
gtk_widget_tap_and_hold_button_press (GtkWidget *widget,
10973
				      GdkEvent  *event,
10974
				      TahData   *td)
10975
{
10976
  if (event->button.type == GDK_2BUTTON_PRESS)
10977
    return FALSE;
10978
10979
  if (!gtk_widget_tap_and_hold_query (widget, event) && !td->timer_id)
10980
    {
10981
      GdkWindow *root_window;
10982
      gdk_display_get_pointer (gtk_widget_get_display (widget),
10983
			       NULL, &td->x, &td->y, NULL);
10984
10985
      td->timer_counter = TAP_AND_HOLD_TIMER_COUNTER;
10986
      /* We set the cursor in the root window for the TAH animation to be
10987
         visible in every possible case, like windows completely covering
10988
         some widget to filter events.
10989
      */
10990
      root_window = gtk_widget_get_root_window (widget);
10991
      if (root_window == NULL)
10992
        {
10993
          /* We are getting events from a widget that's not in a
10994
             hierarchy, it might happen (like putting a dummy widget
10995
             as user_data in a GdkWindow). Try really hard to get
10996
             the root window
10997
          */
10998
          root_window = gdk_screen_get_root_window (gdk_screen_get_default ());
10999
        }
11000
      td->tah_on_window = root_window;
11001
      tap_and_hold_init_animation (td);
11002
      td->timer_id = g_timeout_add (td->interval,
11003
				    (GSourceFunc)
11004
				    gtk_widget_tap_and_hold_timeout, widget);
11005
    }
11006
  return FALSE;
11007
}
11008
11009
static gboolean
11010
gtk_widget_tap_and_hold_event_stop (GtkWidget *widget,
11011
				    gpointer   unused,
11012
				    TahData   *td)
11013
{
11014
  if (td->timer_id)
11015
    tap_and_hold_remove_timer (widget);
11016
11017
  return FALSE;
11018
}
11019
11020
11021
/**
11022
 * gtk_widget_insensitive_press:
11023
 * @widget: a #GtkWidget
11024
 *
11025
 * Emits the "insensitive-press" signal.
11026
 *
11027
 * Deprecated: Use hildon_helper_set_insensitive_message() instead.
11028
 *
11029
 * Since: maemo 1.0
11030
 * Stability: Unstable
11031
 */
11032
void
11033
gtk_widget_insensitive_press ( GtkWidget *widget )
11034
{
11035
  g_return_if_fail (GTK_IS_WIDGET (widget));
11036
  g_signal_emit(widget, widget_signals[INSENSITIVE_PRESS], 0);
11037
}
11038
11039
#define HILDON_HEIGHT_FINGER    70
11040
11041
#define HILDON_HEIGHT_THUMB     105
11042
11043
#define HILDON_WIDTH_FULLSCREEN (gdk_screen_get_width (gdk_screen_get_default ()))
11044
11045
#define HILDON_WIDTH_HALFSCREEN (HILDON_WIDTH_FULLSCREEN / 2)
11046
11047
/**
11048
 * hildon_gtk_widget_set_theme_size:
11049
 * @widget: A #GtkWidget
11050
 * @size: #HildonSizeType flags indicating the size of the widget
11051
 *
11052
 * This function sets the requested size of a widget using one of the
11053
 * predefined sizes.
11054
 *
11055
 * It also changes the widget name (see gtk_widget_set_name()) so it
11056
 * can be themed accordingly.
11057
 *
11058
 * Since: maemo 2.0
11059
 * Stability: Unstable
11060
 **/
11061
void
11062
hildon_gtk_widget_set_theme_size (GtkWidget      *widget,
11063
                                  HildonSizeType  size)
11064
{
11065
  gint width = -1;
11066
  gint height = -1;
11067
  gchar *widget_name = NULL;
11068
11069
  g_return_if_fail (GTK_IS_WIDGET (widget));
11070
11071
  /* Requested height */
11072
  if (size & HILDON_SIZE_FINGER_HEIGHT)
11073
    {
11074
      height = HILDON_HEIGHT_FINGER;
11075
      widget_name = "-finger";
11076
    }
11077
  else if (size & HILDON_SIZE_THUMB_HEIGHT)
11078
    {
11079
      height = HILDON_HEIGHT_THUMB;
11080
      widget_name = "-thumb";
11081
    }
11082
11083
  if (widget_name)
11084
    widget_name = g_strconcat (g_type_name (GTK_WIDGET_TYPE (widget)),
11085
                               widget_name, NULL);
11086
11087
    /* Requested width */
11088
  if (size & HILDON_SIZE_HALFSCREEN_WIDTH)
11089
    width = HILDON_WIDTH_HALFSCREEN;
11090
  else if (size & HILDON_SIZE_FULLSCREEN_WIDTH)
11091
    width = HILDON_WIDTH_FULLSCREEN;
11092
11093
  gtk_widget_set_size_request (widget, width, height);
11094
11095
  if (widget_name)
11096
    {
11097
      gtk_widget_set_name (widget, widget_name);
11098
      g_free (widget_name);
11099
    }
11100
}
11101
#endif /* MAEMO_CHANGES */
11102
11103
11104
#define __GTK_WIDGET_C__
11105
#include "gtkaliasdef.c"