]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gtklabelaccessible.c
c88b7d7d8e30f82ebd64e3d7530396b512080ef1
[~andy/gtk] / gtk / a11y / gtklabelaccessible.c
1 /* GTK+ - accessibility implementations
2  * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
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, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include <gtk/gtk.h>
21 #include <gtk/gtkpango.h>
22 #include "gtklabelaccessible.h"
23
24 struct _GtkLabelAccessiblePrivate
25 {
26   gchar *text;
27   gint cursor_position;
28   gint selection_bound;
29 };
30
31 static void atk_text_interface_init (AtkTextIface *iface);
32
33 G_DEFINE_TYPE_WITH_CODE (GtkLabelAccessible, gtk_label_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
34                          G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
35
36 static void
37 gtk_label_accessible_init (GtkLabelAccessible *label)
38 {
39   label->priv = G_TYPE_INSTANCE_GET_PRIVATE (label,
40                                              GTK_TYPE_LABEL_ACCESSIBLE,
41                                              GtkLabelAccessiblePrivate);
42 }
43
44 static void
45 gtk_label_accessible_initialize (AtkObject *obj,
46                                  gpointer   data)
47 {
48   GtkWidget  *widget;
49   GtkLabelAccessible *accessible;
50
51   ATK_OBJECT_CLASS (gtk_label_accessible_parent_class)->initialize (obj, data);
52
53   accessible = GTK_LABEL_ACCESSIBLE (obj);
54
55   widget = GTK_WIDGET (data);
56
57   accessible->priv->text = g_strdup (gtk_label_get_text (GTK_LABEL (widget)));
58
59   /*
60    * Check whether ancestor of GtkLabel is a GtkButton and if so
61    * set accessible parent for GtkLabelAccessible
62    */
63   while (widget != NULL)
64     {
65       widget = gtk_widget_get_parent (widget);
66       if (GTK_IS_BUTTON (widget))
67         {
68           atk_object_set_parent (obj, gtk_widget_get_accessible (widget));
69           break;
70         }
71     }
72
73   obj->role = ATK_ROLE_LABEL;
74 }
75
76 static gboolean
77 check_for_selection_change (GtkLabelAccessible *accessible,
78                             GtkLabel           *label)
79 {
80   gboolean ret_val = FALSE;
81   gint start, end;
82
83   if (gtk_label_get_selection_bounds (label, &start, &end))
84     {
85       if (end != accessible->priv->cursor_position ||
86           start != accessible->priv->selection_bound)
87         ret_val = TRUE;
88     }
89   else
90     {
91       ret_val = (accessible->priv->cursor_position != accessible->priv->selection_bound);
92     }
93
94   accessible->priv->cursor_position = end;
95   accessible->priv->selection_bound = start;
96
97   return ret_val;
98 }
99
100
101 static void
102 gtk_label_accessible_notify_gtk (GObject    *obj,
103                                  GParamSpec *pspec)
104 {
105   GtkWidget *widget = GTK_WIDGET (obj);
106   AtkObject* atk_obj = gtk_widget_get_accessible (widget);
107   GtkLabelAccessible *accessible;
108   gint length;
109
110   accessible = GTK_LABEL_ACCESSIBLE (atk_obj);
111
112   if (g_strcmp0 (pspec->name, "label") == 0)
113     {
114       const gchar *text;
115
116       text = gtk_label_get_text (GTK_LABEL (widget));
117       if (g_strcmp0 (accessible->priv->text, text) == 0)
118         return;
119
120       /* Create a delete text and an insert text signal */
121       length = g_utf8_strlen (accessible->priv->text, -1);
122       if (length > 0)
123         g_signal_emit_by_name (atk_obj, "text-changed::delete", 0, length);
124
125       g_free (accessible->priv->text);
126       accessible->priv->text = g_strdup (text);
127
128       length = g_utf8_strlen (accessible->priv->text, -1);
129       if (length > 0)
130         g_signal_emit_by_name (atk_obj, "text-changed::insert", 0, length);
131
132       if (atk_obj->name == NULL)
133         /* The label has changed so notify a change in accessible-name */
134         g_object_notify (G_OBJECT (atk_obj), "accessible-name");
135
136       g_signal_emit_by_name (atk_obj, "visible-data-changed");
137     }
138   else if (g_strcmp0 (pspec->name, "cursor-position") == 0)
139     {
140       g_signal_emit_by_name (atk_obj, "text-caret-moved",
141                              _gtk_label_get_cursor_position (GTK_LABEL (widget)));
142       if (check_for_selection_change (accessible, GTK_LABEL (widget)))
143         g_signal_emit_by_name (atk_obj, "text-selection-changed");
144     }
145   else if (g_strcmp0 (pspec->name, "selection-bound") == 0)
146     {
147       if (check_for_selection_change (accessible, GTK_LABEL (widget)))
148         g_signal_emit_by_name (atk_obj, "text-selection-changed");
149     }
150   else
151     GTK_WIDGET_ACCESSIBLE_CLASS (gtk_label_accessible_parent_class)->notify_gtk (obj, pspec);
152 }
153
154 static void
155 gtk_label_accessible_finalize (GObject *object)
156 {
157   GtkLabelAccessible *accessible = GTK_LABEL_ACCESSIBLE (object);
158
159   g_free (accessible->priv->text);
160
161   G_OBJECT_CLASS (gtk_label_accessible_parent_class)->finalize (object);
162 }
163
164
165 /* atkobject.h */
166
167 static AtkStateSet *
168 gtk_label_accessible_ref_state_set (AtkObject *accessible)
169 {
170   AtkStateSet *state_set;
171   GtkWidget *widget;
172
173   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
174   if (widget == NULL)
175     return NULL;
176
177   state_set = ATK_OBJECT_CLASS (gtk_label_accessible_parent_class)->ref_state_set (accessible);
178   atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
179
180   return state_set;
181 }
182
183 static AtkRelationSet *
184 gtk_label_accessible_ref_relation_set (AtkObject *obj)
185 {
186   GtkWidget *widget;
187   AtkRelationSet *relation_set;
188
189   g_return_val_if_fail (GTK_IS_LABEL_ACCESSIBLE (obj), NULL);
190
191   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
192   if (widget == NULL)
193     return NULL;
194
195   relation_set = ATK_OBJECT_CLASS (gtk_label_accessible_parent_class)->ref_relation_set (obj);
196
197   if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABEL_FOR))
198     {
199       /* Get the mnemonic widget.
200        * The relation set is not updated if the mnemonic widget is changed
201        */
202       GtkWidget *mnemonic_widget;
203
204       mnemonic_widget = gtk_label_get_mnemonic_widget (GTK_LABEL (widget));
205
206       if (mnemonic_widget)
207         {
208           AtkObject *accessible_array[1];
209           AtkRelation* relation;
210
211           if (!gtk_widget_get_can_focus (mnemonic_widget))
212             {
213             /*
214              * Handle the case where a GtkFileChooserButton is specified
215              * as the mnemonic widget. use the combobox which is a child of the
216              * GtkFileChooserButton as the mnemonic widget. See bug #359843.
217              */
218              if (GTK_IS_BOX (mnemonic_widget))
219                {
220                   GList *list, *tmpl;
221
222                   list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget));
223                   if (g_list_length (list) == 2)
224                     {
225                       tmpl = g_list_last (list);
226                       if (GTK_IS_COMBO_BOX(tmpl->data))
227                         {
228                           mnemonic_widget = GTK_WIDGET(tmpl->data);
229                         }
230                     }
231                   g_list_free (list);
232                 }
233             }
234           accessible_array[0] = gtk_widget_get_accessible (mnemonic_widget);
235           relation = atk_relation_new (accessible_array, 1,
236                                        ATK_RELATION_LABEL_FOR);
237           atk_relation_set_add (relation_set, relation);
238           /*
239            * Unref the relation so that it is not leaked.
240            */
241           g_object_unref (relation);
242         }
243     }
244   return relation_set;
245 }
246
247 static const gchar*
248 gtk_label_accessible_get_name (AtkObject *accessible)
249 {
250   const gchar *name;
251
252   g_return_val_if_fail (GTK_IS_LABEL_ACCESSIBLE (accessible), NULL);
253
254   name = ATK_OBJECT_CLASS (gtk_label_accessible_parent_class)->get_name (accessible);
255   if (name != NULL)
256     return name;
257   else
258     {
259       /*
260        * Get the text on the label
261        */
262       GtkWidget *widget;
263
264       widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
265       if (widget == NULL)
266         return NULL;
267
268       g_return_val_if_fail (GTK_IS_LABEL (widget), NULL);
269
270       return gtk_label_get_text (GTK_LABEL (widget));
271     }
272 }
273
274 static void
275 gtk_label_accessible_class_init (GtkLabelAccessibleClass *klass)
276 {
277   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
278   AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
279   GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
280
281   gobject_class->finalize = gtk_label_accessible_finalize;
282
283   widget_class->notify_gtk = gtk_label_accessible_notify_gtk;
284
285   class->get_name = gtk_label_accessible_get_name;
286   class->ref_state_set = gtk_label_accessible_ref_state_set;
287   class->ref_relation_set = gtk_label_accessible_ref_relation_set;
288   class->initialize = gtk_label_accessible_initialize;
289
290   g_type_class_add_private (klass, sizeof (GtkLabelAccessiblePrivate));
291 }
292
293 /* atktext.h */
294
295 static gchar*
296 gtk_label_accessible_get_text (AtkText *atk_text,
297                                gint     start_pos,
298                                gint     end_pos)
299 {
300   GtkWidget *widget;
301   const gchar *text;
302
303   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
304   if (widget == NULL)
305     return NULL;
306
307   text = gtk_label_get_text (GTK_LABEL (widget));
308
309   if (text)
310     {
311       guint length;
312       const gchar *start, *end;
313
314       length = g_utf8_strlen (text, -1);
315       if (end_pos < 0 || end_pos > length)
316         end_pos = length;
317       if (start_pos > length)
318         start_pos = length;
319       if (end_pos <= start_pos)
320         return g_strdup ("");
321       start = g_utf8_offset_to_pointer (text, start_pos);
322       end = g_utf8_offset_to_pointer (start, end_pos - start_pos);
323       return g_strndup (start, end - start);
324     }
325
326   return NULL;
327 }
328
329 static gchar *
330 gtk_label_accessible_get_text_before_offset (AtkText         *text,
331                                              gint             offset,
332                                              AtkTextBoundary  boundary_type,
333                                              gint            *start_offset,
334                                              gint            *end_offset)
335 {
336   GtkWidget *widget;
337
338   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
339   if (widget == NULL)
340     return NULL;
341
342   return _gtk_pango_get_text_before (gtk_label_get_layout (GTK_LABEL (widget)),
343                                      boundary_type, offset,
344                                      start_offset, end_offset);
345 }
346
347 static gchar*
348 gtk_label_accessible_get_text_at_offset (AtkText         *text,
349                                          gint             offset,
350                                          AtkTextBoundary  boundary_type,
351                                          gint            *start_offset,
352                                          gint            *end_offset)
353 {
354   GtkWidget *widget;
355
356   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
357   if (widget == NULL)
358     return NULL;
359
360   return _gtk_pango_get_text_at (gtk_label_get_layout (GTK_LABEL (widget)),
361                                  boundary_type, offset,
362                                  start_offset, end_offset);
363 }
364
365 static gchar*
366 gtk_label_accessible_get_text_after_offset (AtkText         *text,
367                                             gint             offset,
368                                             AtkTextBoundary  boundary_type,
369                                             gint            *start_offset,
370                                             gint            *end_offset)
371 {
372   GtkWidget *widget;
373
374   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
375   if (widget == NULL)
376     return NULL;
377
378   return _gtk_pango_get_text_after (gtk_label_get_layout (GTK_LABEL (widget)),
379                                     boundary_type, offset,
380                                     start_offset, end_offset);
381 }
382
383 static gint
384 gtk_label_accessible_get_character_count (AtkText *atk_text)
385 {
386   GtkWidget *widget;
387   const gchar *text;
388
389   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
390   if (widget == NULL)
391     return 0;
392
393   text = gtk_label_get_text (GTK_LABEL (widget));
394
395   if (text)
396     return g_utf8_strlen (text, -1);
397
398   return 0;
399 }
400
401 static gint
402 gtk_label_accessible_get_caret_offset (AtkText *text)
403 {
404   GtkWidget *widget;
405
406   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
407   if (widget == NULL)
408     return 0;
409
410   return _gtk_label_get_cursor_position (GTK_LABEL (widget));
411 }
412
413 static gboolean
414 gtk_label_accessible_set_caret_offset (AtkText *text,
415                                        gint     offset)
416 {
417   GtkWidget *widget;
418   GtkLabel *label;
419
420   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
421   if (widget == NULL)
422     return FALSE;
423
424   label = GTK_LABEL (widget);
425
426   if (!gtk_label_get_selectable (label))
427     return FALSE;
428
429   gtk_label_select_region (label, offset, offset);
430
431   return TRUE;
432 }
433
434 static gint
435 gtk_label_accessible_get_n_selections (AtkText *text)
436 {
437   GtkWidget *widget;
438
439   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
440   if (widget == NULL)
441     return 0;
442
443   if (gtk_label_get_selection_bounds (GTK_LABEL (widget), NULL, NULL))
444     return 1;
445
446   return 0;
447 }
448
449 static gchar *
450 gtk_label_accessible_get_selection (AtkText *atk_text,
451                                     gint     selection_num,
452                                     gint    *start_pos,
453                                     gint    *end_pos)
454 {
455   GtkWidget *widget;
456   GtkLabel  *label;
457
458   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
459   if (widget == NULL)
460     return NULL;
461
462   if (selection_num != 0)
463     return NULL;
464
465   label = GTK_LABEL (widget);
466
467   if (gtk_label_get_selection_bounds (label, start_pos, end_pos))
468     {
469       const gchar *text;
470
471       text = gtk_label_get_text (label);
472
473       if (text)
474         return g_utf8_substring (text, *start_pos, *end_pos);
475     }
476
477   return NULL;
478 }
479
480 static gboolean
481 gtk_label_accessible_add_selection (AtkText *text,
482                                     gint     start_pos,
483                                     gint     end_pos)
484 {
485   GtkWidget *widget;
486   GtkLabel  *label;
487   gint start, end;
488
489   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
490   if (widget == NULL)
491     return FALSE;
492
493   label = GTK_LABEL (widget);
494
495   if (!gtk_label_get_selectable (label))
496     return FALSE;
497
498   if (!gtk_label_get_selection_bounds (label, &start, &end))
499     {
500       gtk_label_select_region (label, start_pos, end_pos);
501       return TRUE;
502     }
503   else
504     return FALSE;
505 }
506
507 static gboolean
508 gtk_label_accessible_remove_selection (AtkText *text,
509                                        gint     selection_num)
510 {
511   GtkWidget *widget;
512   GtkLabel  *label;
513   gint start, end;
514
515   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
516   if (widget == NULL)
517     return FALSE;
518
519   if (selection_num != 0)
520      return FALSE;
521
522   label = GTK_LABEL (widget);
523
524   if (!gtk_label_get_selectable (label))
525      return FALSE;
526
527   if (gtk_label_get_selection_bounds (label, &start, &end))
528     {
529       gtk_label_select_region (label, end, end);
530       return TRUE;
531     }
532   else
533     return FALSE;
534 }
535
536 static gboolean
537 gtk_label_accessible_set_selection (AtkText *text,
538                                     gint     selection_num,
539                                     gint     start_pos,
540                                     gint     end_pos)
541 {
542   GtkWidget *widget;
543   GtkLabel  *label;
544   gint start, end;
545
546   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
547   if (widget == NULL)
548     return FALSE;
549
550   if (selection_num != 0)
551     return FALSE;
552
553   label = GTK_LABEL (widget);
554
555   if (!gtk_label_get_selectable (label))
556     return FALSE;
557
558   if (gtk_label_get_selection_bounds (label, &start, &end))
559     {
560       gtk_label_select_region (label, start_pos, end_pos);
561       return TRUE;
562     }
563   else
564     return FALSE;
565 }
566
567 static void
568 gtk_label_accessible_get_character_extents (AtkText      *text,
569                                             gint          offset,
570                                             gint         *x,
571                                             gint         *y,
572                                             gint         *width,
573                                             gint         *height,
574                                             AtkCoordType  coords)
575 {
576   GtkWidget *widget;
577   GtkLabel *label;
578   PangoRectangle char_rect;
579   const gchar *label_text;
580   gint index, x_layout, y_layout;
581   GdkWindow *window;
582   gint x_window, y_window;
583
584   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
585   if (widget == NULL)
586     return;
587
588   label = GTK_LABEL (widget);
589
590   gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
591   label_text = gtk_label_get_text (label);
592   index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
593   pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect);
594   pango_extents_to_pixels (&char_rect, NULL);
595
596   window = gtk_widget_get_window (widget);
597   gdk_window_get_origin (window, &x_window, &y_window);
598
599   *x = x_window + x_layout + char_rect.x;
600   *y = y_window + y_layout + char_rect.y;
601   *width = char_rect.width;
602   *height = char_rect.height;
603
604   if (coords == ATK_XY_WINDOW)
605     {
606       window = gdk_window_get_toplevel (window);
607       gdk_window_get_origin (window, &x_window, &y_window);
608
609       *x -= x_window;
610       *y -= y_window;
611     }
612 }
613
614 static gint
615 gtk_label_accessible_get_offset_at_point (AtkText      *atk_text,
616                                           gint          x,
617                                           gint          y,
618                                           AtkCoordType  coords)
619 {
620   GtkWidget *widget;
621   GtkLabel *label;
622   const gchar *text;
623   gint index, x_layout, y_layout;
624   gint x_window, y_window;
625   gint x_local, y_local;
626   GdkWindow *window;
627
628   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
629   if (widget == NULL)
630     return -1;
631
632   label = GTK_LABEL (widget);
633
634   gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
635
636   window = gtk_widget_get_window (widget);
637   gdk_window_get_origin (window, &x_window, &y_window);
638
639   x_local = x - x_layout - x_window;
640   y_local = y - y_layout - y_window;
641
642   if (coords == ATK_XY_WINDOW)
643     {
644       window = gdk_window_get_toplevel (window);
645       gdk_window_get_origin (window, &x_window, &y_window);
646
647       x_local += x_window;
648       y_local += y_window;
649     }
650
651   if (!pango_layout_xy_to_index (gtk_label_get_layout (label),
652                                  x_local * PANGO_SCALE,
653                                  y_local * PANGO_SCALE,
654                                  &index, NULL))
655     {
656       if (x_local < 0 || y_local < 0)
657         index = 0;
658       else
659         index = -1;
660     }
661
662   if (index != -1)
663     {
664       text = gtk_label_get_text (label);
665       return g_utf8_pointer_to_offset (text, text + index);
666     }
667
668   return -1;
669 }
670
671 static AtkAttributeSet *
672 add_attribute (AtkAttributeSet  *attributes,
673                AtkTextAttribute  attr,
674                const gchar      *value)
675 {
676   AtkAttribute *at;
677
678   at = g_new (AtkAttribute, 1);
679   at->name = g_strdup (atk_text_attribute_get_name (attr));
680   at->value = g_strdup (value);
681
682   return g_slist_prepend (attributes, at);
683 }
684
685 static AtkAttributeSet*
686 gtk_label_accessible_get_run_attributes (AtkText *text,
687                                          gint     offset,
688                                          gint    *start_offset,
689                                          gint    *end_offset)
690 {
691   GtkWidget *widget;
692   AtkAttributeSet *attributes;
693
694   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
695   if (widget == NULL)
696     return NULL;
697
698   attributes = NULL;
699   attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
700                    atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
701                                                  gtk_widget_get_direction (widget)));
702   attributes = _gtk_pango_get_run_attributes (attributes,
703                                               gtk_label_get_layout (GTK_LABEL (widget)),
704                                               offset,
705                                               start_offset,
706                                               end_offset);
707
708   return attributes;
709 }
710
711 static AtkAttributeSet *
712 gtk_label_accessible_get_default_attributes (AtkText *text)
713 {
714   GtkWidget *widget;
715   AtkAttributeSet *attributes;
716
717   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
718   if (widget == NULL)
719     return NULL;
720
721   attributes = NULL;
722   attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
723                    atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
724                                                  gtk_widget_get_direction (widget)));
725   attributes = _gtk_pango_get_default_attributes (attributes,
726                                                   gtk_label_get_layout (GTK_LABEL (widget)));
727   attributes = _gtk_style_context_get_attributes (attributes,
728                                                   gtk_widget_get_style_context (widget),
729                                                   gtk_widget_get_state_flags (widget));
730
731   return attributes;
732 }
733
734 static gunichar
735 gtk_label_accessible_get_character_at_offset (AtkText *atk_text,
736                                               gint     offset)
737 {
738   GtkWidget *widget;
739   const gchar *text;
740   gchar *index;
741
742   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
743   if (widget == NULL)
744     return '\0';
745
746   text = gtk_label_get_text (GTK_LABEL (widget));
747   if (offset >= g_utf8_strlen (text, -1))
748     return '\0';
749
750   index = g_utf8_offset_to_pointer (text, offset);
751
752   return g_utf8_get_char (index);
753 }
754
755 static void
756 atk_text_interface_init (AtkTextIface *iface)
757 {
758   iface->get_text = gtk_label_accessible_get_text;
759   iface->get_character_at_offset = gtk_label_accessible_get_character_at_offset;
760   iface->get_text_before_offset = gtk_label_accessible_get_text_before_offset;
761   iface->get_text_at_offset = gtk_label_accessible_get_text_at_offset;
762   iface->get_text_after_offset = gtk_label_accessible_get_text_after_offset;
763   iface->get_character_count = gtk_label_accessible_get_character_count;
764   iface->get_caret_offset = gtk_label_accessible_get_caret_offset;
765   iface->set_caret_offset = gtk_label_accessible_set_caret_offset;
766   iface->get_n_selections = gtk_label_accessible_get_n_selections;
767   iface->get_selection = gtk_label_accessible_get_selection;
768   iface->add_selection = gtk_label_accessible_add_selection;
769   iface->remove_selection = gtk_label_accessible_remove_selection;
770   iface->set_selection = gtk_label_accessible_set_selection;
771   iface->get_character_extents = gtk_label_accessible_get_character_extents;
772   iface->get_offset_at_point = gtk_label_accessible_get_offset_at_point;
773   iface->get_run_attributes = gtk_label_accessible_get_run_attributes;
774   iface->get_default_attributes = gtk_label_accessible_get_default_attributes;
775 }
776