]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gtklabelaccessible.c
filechooser: Rename _gtk_file_is_path_not_local() to _gtk_file_has_native_path()
[~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     return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
311
312   return NULL;
313 }
314
315 static gchar *
316 gtk_label_accessible_get_text_before_offset (AtkText         *text,
317                                              gint             offset,
318                                              AtkTextBoundary  boundary_type,
319                                              gint            *start_offset,
320                                              gint            *end_offset)
321 {
322   GtkWidget *widget;
323
324   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
325   if (widget == NULL)
326     return NULL;
327
328   return _gtk_pango_get_text_before (gtk_label_get_layout (GTK_LABEL (widget)),
329                                      boundary_type, offset,
330                                      start_offset, end_offset);
331 }
332
333 static gchar*
334 gtk_label_accessible_get_text_at_offset (AtkText         *text,
335                                          gint             offset,
336                                          AtkTextBoundary  boundary_type,
337                                          gint            *start_offset,
338                                          gint            *end_offset)
339 {
340   GtkWidget *widget;
341
342   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
343   if (widget == NULL)
344     return NULL;
345
346   return _gtk_pango_get_text_at (gtk_label_get_layout (GTK_LABEL (widget)),
347                                  boundary_type, offset,
348                                  start_offset, end_offset);
349 }
350
351 static gchar*
352 gtk_label_accessible_get_text_after_offset (AtkText         *text,
353                                             gint             offset,
354                                             AtkTextBoundary  boundary_type,
355                                             gint            *start_offset,
356                                             gint            *end_offset)
357 {
358   GtkWidget *widget;
359
360   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
361   if (widget == NULL)
362     return NULL;
363
364   return _gtk_pango_get_text_after (gtk_label_get_layout (GTK_LABEL (widget)),
365                                     boundary_type, offset,
366                                     start_offset, end_offset);
367 }
368
369 static gint
370 gtk_label_accessible_get_character_count (AtkText *atk_text)
371 {
372   GtkWidget *widget;
373   const gchar *text;
374
375   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
376   if (widget == NULL)
377     return 0;
378
379   text = gtk_label_get_text (GTK_LABEL (widget));
380
381   if (text)
382     return g_utf8_strlen (text, -1);
383
384   return 0;
385 }
386
387 static gint
388 gtk_label_accessible_get_caret_offset (AtkText *text)
389 {
390   GtkWidget *widget;
391
392   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
393   if (widget == NULL)
394     return 0;
395
396   return _gtk_label_get_cursor_position (GTK_LABEL (widget));
397 }
398
399 static gboolean
400 gtk_label_accessible_set_caret_offset (AtkText *text,
401                                        gint     offset)
402 {
403   GtkWidget *widget;
404   GtkLabel *label;
405
406   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
407   if (widget == NULL)
408     return FALSE;
409
410   label = GTK_LABEL (widget);
411
412   if (!gtk_label_get_selectable (label))
413     return FALSE;
414
415   gtk_label_select_region (label, offset, offset);
416
417   return TRUE;
418 }
419
420 static gint
421 gtk_label_accessible_get_n_selections (AtkText *text)
422 {
423   GtkWidget *widget;
424
425   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
426   if (widget == NULL)
427     return 0;
428
429   if (gtk_label_get_selection_bounds (GTK_LABEL (widget), NULL, NULL))
430     return 1;
431
432   return 0;
433 }
434
435 static gchar *
436 gtk_label_accessible_get_selection (AtkText *atk_text,
437                                     gint     selection_num,
438                                     gint    *start_pos,
439                                     gint    *end_pos)
440 {
441   GtkWidget *widget;
442   GtkLabel  *label;
443
444   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
445   if (widget == NULL)
446     return NULL;
447
448   if (selection_num != 0)
449     return NULL;
450
451   label = GTK_LABEL (widget);
452
453   if (gtk_label_get_selection_bounds (label, start_pos, end_pos))
454     {
455       const gchar *text;
456
457       text = gtk_label_get_text (label);
458
459       if (text)
460         return g_utf8_substring (text, *start_pos, *end_pos);
461     }
462
463   return NULL;
464 }
465
466 static gboolean
467 gtk_label_accessible_add_selection (AtkText *text,
468                                     gint     start_pos,
469                                     gint     end_pos)
470 {
471   GtkWidget *widget;
472   GtkLabel  *label;
473   gint start, end;
474
475   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
476   if (widget == NULL)
477     return FALSE;
478
479   label = GTK_LABEL (widget);
480
481   if (!gtk_label_get_selectable (label))
482     return FALSE;
483
484   if (!gtk_label_get_selection_bounds (label, &start, &end))
485     {
486       gtk_label_select_region (label, start_pos, end_pos);
487       return TRUE;
488     }
489   else
490     return FALSE;
491 }
492
493 static gboolean
494 gtk_label_accessible_remove_selection (AtkText *text,
495                                        gint     selection_num)
496 {
497   GtkWidget *widget;
498   GtkLabel  *label;
499   gint start, end;
500
501   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
502   if (widget == NULL)
503     return FALSE;
504
505   if (selection_num != 0)
506      return FALSE;
507
508   label = GTK_LABEL (widget);
509
510   if (!gtk_label_get_selectable (label))
511      return FALSE;
512
513   if (gtk_label_get_selection_bounds (label, &start, &end))
514     {
515       gtk_label_select_region (label, end, end);
516       return TRUE;
517     }
518   else
519     return FALSE;
520 }
521
522 static gboolean
523 gtk_label_accessible_set_selection (AtkText *text,
524                                     gint     selection_num,
525                                     gint     start_pos,
526                                     gint     end_pos)
527 {
528   GtkWidget *widget;
529   GtkLabel  *label;
530   gint start, end;
531
532   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
533   if (widget == NULL)
534     return FALSE;
535
536   if (selection_num != 0)
537     return FALSE;
538
539   label = GTK_LABEL (widget);
540
541   if (!gtk_label_get_selectable (label))
542     return FALSE;
543
544   if (gtk_label_get_selection_bounds (label, &start, &end))
545     {
546       gtk_label_select_region (label, start_pos, end_pos);
547       return TRUE;
548     }
549   else
550     return FALSE;
551 }
552
553 static void
554 gtk_label_accessible_get_character_extents (AtkText      *text,
555                                             gint          offset,
556                                             gint         *x,
557                                             gint         *y,
558                                             gint         *width,
559                                             gint         *height,
560                                             AtkCoordType  coords)
561 {
562   GtkWidget *widget;
563   GtkLabel *label;
564   PangoRectangle char_rect;
565   const gchar *label_text;
566   gint index, x_layout, y_layout;
567   GdkWindow *window;
568   gint x_window, y_window;
569
570   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
571   if (widget == NULL)
572     return;
573
574   label = GTK_LABEL (widget);
575
576   gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
577   label_text = gtk_label_get_text (label);
578   index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
579   pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect);
580   pango_extents_to_pixels (&char_rect, NULL);
581
582   window = gtk_widget_get_window (widget);
583   gdk_window_get_origin (window, &x_window, &y_window);
584
585   *x = x_window + x_layout + char_rect.x;
586   *y = y_window + y_layout + char_rect.y;
587   *width = char_rect.width;
588   *height = char_rect.height;
589
590   if (coords == ATK_XY_WINDOW)
591     {
592       window = gdk_window_get_toplevel (window);
593       gdk_window_get_origin (window, &x_window, &y_window);
594
595       *x -= x_window;
596       *y -= y_window;
597     }
598 }
599
600 static gint
601 gtk_label_accessible_get_offset_at_point (AtkText      *atk_text,
602                                           gint          x,
603                                           gint          y,
604                                           AtkCoordType  coords)
605 {
606   GtkWidget *widget;
607   GtkLabel *label;
608   const gchar *text;
609   gint index, x_layout, y_layout;
610   gint x_window, y_window;
611   gint x_local, y_local;
612   GdkWindow *window;
613
614   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
615   if (widget == NULL)
616     return -1;
617
618   label = GTK_LABEL (widget);
619
620   gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
621
622   window = gtk_widget_get_window (widget);
623   gdk_window_get_origin (window, &x_window, &y_window);
624
625   x_local = x - x_layout - x_window;
626   y_local = y - y_layout - y_window;
627
628   if (coords == ATK_XY_WINDOW)
629     {
630       window = gdk_window_get_toplevel (window);
631       gdk_window_get_origin (window, &x_window, &y_window);
632
633       x_local += x_window;
634       y_local += y_window;
635     }
636
637   if (!pango_layout_xy_to_index (gtk_label_get_layout (label),
638                                  x_local * PANGO_SCALE,
639                                  y_local * PANGO_SCALE,
640                                  &index, NULL))
641     {
642       if (x_local < 0 || y_local < 0)
643         index = 0;
644       else
645         index = -1;
646     }
647
648   if (index != -1)
649     {
650       text = gtk_label_get_text (label);
651       return g_utf8_pointer_to_offset (text, text + index);
652     }
653
654   return -1;
655 }
656
657 static AtkAttributeSet *
658 add_attribute (AtkAttributeSet  *attributes,
659                AtkTextAttribute  attr,
660                const gchar      *value)
661 {
662   AtkAttribute *at;
663
664   at = g_new (AtkAttribute, 1);
665   at->name = g_strdup (atk_text_attribute_get_name (attr));
666   at->value = g_strdup (value);
667
668   return g_slist_prepend (attributes, at);
669 }
670
671 static AtkAttributeSet*
672 gtk_label_accessible_get_run_attributes (AtkText *text,
673                                          gint     offset,
674                                          gint    *start_offset,
675                                          gint    *end_offset)
676 {
677   GtkWidget *widget;
678   AtkAttributeSet *attributes;
679
680   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
681   if (widget == NULL)
682     return NULL;
683
684   attributes = NULL;
685   attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
686                    atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
687                                                  gtk_widget_get_direction (widget)));
688   attributes = _gtk_pango_get_run_attributes (attributes,
689                                               gtk_label_get_layout (GTK_LABEL (widget)),
690                                               offset,
691                                               start_offset,
692                                               end_offset);
693
694   return attributes;
695 }
696
697 static AtkAttributeSet *
698 gtk_label_accessible_get_default_attributes (AtkText *text)
699 {
700   GtkWidget *widget;
701   AtkAttributeSet *attributes;
702
703   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
704   if (widget == NULL)
705     return NULL;
706
707   attributes = NULL;
708   attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
709                    atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
710                                                  gtk_widget_get_direction (widget)));
711   attributes = _gtk_pango_get_default_attributes (attributes,
712                                                   gtk_label_get_layout (GTK_LABEL (widget)));
713   attributes = _gtk_style_context_get_attributes (attributes,
714                                                   gtk_widget_get_style_context (widget),
715                                                   gtk_widget_get_state_flags (widget));
716
717   return attributes;
718 }
719
720 static gunichar
721 gtk_label_accessible_get_character_at_offset (AtkText *atk_text,
722                                               gint     offset)
723 {
724   GtkWidget *widget;
725   const gchar *text;
726   gchar *index;
727
728   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
729   if (widget == NULL)
730     return '\0';
731
732   text = gtk_label_get_text (GTK_LABEL (widget));
733   if (offset >= g_utf8_strlen (text, -1))
734     return '\0';
735
736   index = g_utf8_offset_to_pointer (text, offset);
737
738   return g_utf8_get_char (index);
739 }
740
741 static void
742 atk_text_interface_init (AtkTextIface *iface)
743 {
744   iface->get_text = gtk_label_accessible_get_text;
745   iface->get_character_at_offset = gtk_label_accessible_get_character_at_offset;
746   iface->get_text_before_offset = gtk_label_accessible_get_text_before_offset;
747   iface->get_text_at_offset = gtk_label_accessible_get_text_at_offset;
748   iface->get_text_after_offset = gtk_label_accessible_get_text_after_offset;
749   iface->get_character_count = gtk_label_accessible_get_character_count;
750   iface->get_caret_offset = gtk_label_accessible_get_caret_offset;
751   iface->set_caret_offset = gtk_label_accessible_set_caret_offset;
752   iface->get_n_selections = gtk_label_accessible_get_n_selections;
753   iface->get_selection = gtk_label_accessible_get_selection;
754   iface->add_selection = gtk_label_accessible_add_selection;
755   iface->remove_selection = gtk_label_accessible_remove_selection;
756   iface->set_selection = gtk_label_accessible_set_selection;
757   iface->get_character_extents = gtk_label_accessible_get_character_extents;
758   iface->get_offset_at_point = gtk_label_accessible_get_offset_at_point;
759   iface->get_run_attributes = gtk_label_accessible_get_run_attributes;
760   iface->get_default_attributes = gtk_label_accessible_get_default_attributes;
761 }
762