2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2008 Novell, Inc.
6 * Copyright 2001, 2002 Sun Microsystems Inc.,
7 * Copyright 2001, 2002 Ximian, Inc.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
28 #include <droute/droute.h>
33 #include "introspection.h"
36 impl_get_CharacterCount (DBusMessageIter * iter, void *user_data)
38 AtkText *text = (AtkText *) user_data;
39 g_return_val_if_fail (ATK_IS_TEXT (user_data), FALSE);
40 return droute_return_v_int32 (iter, atk_text_get_character_count (text));
44 impl_get_CaretOffset (DBusMessageIter * iter, void *user_data)
46 AtkText *text = (AtkText *) user_data;
47 g_return_val_if_fail (ATK_IS_TEXT (user_data), FALSE);
48 return droute_return_v_int32 (iter, atk_text_get_caret_offset (text));
52 validate_allocated_string (gchar *str)
56 if (!g_utf8_validate (str, -1, NULL))
58 g_warning ("atk-bridge: received bad UTF-8 string from a get_text function");
66 impl_GetText (DBusConnection * bus, DBusMessage * message, void *user_data)
68 AtkText *text = (AtkText *) user_data;
69 dbus_int32_t startOffset, endOffset;
73 g_return_val_if_fail (ATK_IS_TEXT (user_data),
74 droute_not_yet_handled_error (message));
75 if (!dbus_message_get_args
76 (message, NULL, DBUS_TYPE_INT32, &startOffset, DBUS_TYPE_INT32,
77 &endOffset, DBUS_TYPE_INVALID))
79 return droute_invalid_arguments_error (message);
81 txt = atk_text_get_text (text, startOffset, endOffset);
82 txt = validate_allocated_string (txt);
83 reply = dbus_message_new_method_return (message);
86 dbus_message_append_args (reply, DBUS_TYPE_STRING, &txt,
94 impl_SetCaretOffset (DBusConnection * bus, DBusMessage * message,
97 AtkText *text = (AtkText *) user_data;
102 g_return_val_if_fail (ATK_IS_TEXT (user_data),
103 droute_not_yet_handled_error (message));
104 if (!dbus_message_get_args
105 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_INVALID))
107 return droute_invalid_arguments_error (message);
109 rv = atk_text_set_caret_offset (text, offset);
110 reply = dbus_message_new_method_return (message);
113 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
120 impl_GetTextBeforeOffset (DBusConnection * bus, DBusMessage * message,
123 AtkText *text = (AtkText *) user_data;
127 dbus_int32_t startOffset, endOffset;
128 gint intstart_offset = 0, intend_offset = 0;
131 g_return_val_if_fail (ATK_IS_TEXT (user_data),
132 droute_not_yet_handled_error (message));
133 if (!dbus_message_get_args
134 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_UINT32, &type,
137 return droute_invalid_arguments_error (message);
140 atk_text_get_text_before_offset (text, offset, (AtkTextBoundary) type,
141 &intstart_offset, &intend_offset);
142 startOffset = intstart_offset;
143 endOffset = intend_offset;
144 txt = validate_allocated_string (txt);
145 reply = dbus_message_new_method_return (message);
148 dbus_message_append_args (reply, DBUS_TYPE_STRING, &txt,
149 DBUS_TYPE_INT32, &startOffset,
150 DBUS_TYPE_INT32, &endOffset,
158 impl_GetTextAtOffset (DBusConnection * bus, DBusMessage * message,
161 AtkText *text = (AtkText *) user_data;
162 dbus_int32_t offset, type;
164 dbus_int32_t startOffset, endOffset;
165 gint intstart_offset = 0, intend_offset = 0;
168 g_return_val_if_fail (ATK_IS_TEXT (user_data),
169 droute_not_yet_handled_error (message));
170 if (!dbus_message_get_args
171 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_UINT32, &type,
174 return droute_invalid_arguments_error (message);
177 atk_text_get_text_at_offset (text, offset, (AtkTextBoundary) type,
178 &intstart_offset, &intend_offset);
179 startOffset = intstart_offset;
180 endOffset = intend_offset;
181 txt = validate_allocated_string (txt);
182 reply = dbus_message_new_method_return (message);
185 dbus_message_append_args (reply, DBUS_TYPE_STRING, &txt,
186 DBUS_TYPE_INT32, &startOffset,
187 DBUS_TYPE_INT32, &endOffset,
195 impl_GetTextAfterOffset (DBusConnection * bus, DBusMessage * message,
198 AtkText *text = (AtkText *) user_data;
202 dbus_int32_t startOffset, endOffset;
203 gint intstart_offset = 0, intend_offset = 0;
206 g_return_val_if_fail (ATK_IS_TEXT (user_data),
207 droute_not_yet_handled_error (message));
208 if (!dbus_message_get_args
209 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_UINT32, &type,
212 return droute_invalid_arguments_error (message);
215 atk_text_get_text_after_offset (text, offset, (AtkTextBoundary) type,
216 &intstart_offset, &intend_offset);
217 startOffset = intstart_offset;
218 endOffset = intend_offset;
219 txt = validate_allocated_string (txt);
220 reply = dbus_message_new_method_return (message);
223 dbus_message_append_args (reply, DBUS_TYPE_STRING, &txt,
224 DBUS_TYPE_INT32, &startOffset,
225 DBUS_TYPE_INT32, &endOffset,
233 impl_GetCharacterAtOffset (DBusConnection * bus, DBusMessage * message,
236 AtkText *text = (AtkText *) user_data;
241 g_return_val_if_fail (ATK_IS_TEXT (user_data),
242 droute_not_yet_handled_error (message));
243 if (!dbus_message_get_args
244 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_INVALID))
246 return droute_invalid_arguments_error (message);
248 ch = atk_text_get_character_at_offset (text, offset);
249 reply = dbus_message_new_method_return (message);
252 dbus_message_append_args (reply, DBUS_TYPE_INT32, &ch,
259 get_text_for_legacy_implementations(AtkText *text,
261 AtkTextGranularity granularity,
266 AtkTextBoundary boundary = 0;
267 switch (granularity) {
268 case ATK_TEXT_GRANULARITY_CHAR:
269 boundary = ATK_TEXT_BOUNDARY_CHAR;
272 case ATK_TEXT_GRANULARITY_WORD:
273 boundary = ATK_TEXT_BOUNDARY_WORD_START;
276 case ATK_TEXT_GRANULARITY_SENTENCE:
277 boundary = ATK_TEXT_BOUNDARY_SENTENCE_START;
280 case ATK_TEXT_GRANULARITY_LINE:
281 boundary = ATK_TEXT_BOUNDARY_LINE_START;
284 case ATK_TEXT_GRANULARITY_PARAGRAPH:
285 /* This is not implemented in previous versions of ATK */
290 g_assert_not_reached();
296 atk_text_get_text_at_offset (text, offset, boundary,
297 start_offset, end_offset);
304 impl_GetStringAtOffset (DBusConnection * bus, DBusMessage * message,
307 AtkText *text = (AtkText *) user_data;
309 dbus_uint32_t granularity;
311 dbus_int32_t startOffset, endOffset;
312 gint intstart_offset = 0, intend_offset = 0;
315 g_return_val_if_fail (ATK_IS_TEXT (user_data),
316 droute_not_yet_handled_error (message));
317 if (!dbus_message_get_args
318 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_UINT32, &granularity,
321 return droute_invalid_arguments_error (message);
325 atk_text_get_string_at_offset (text, offset, (AtkTextGranularity) granularity,
326 &intstart_offset, &intend_offset);
328 /* Accessibility layers implementing an older version of ATK (even if
329 * a new enough version of libatk is installed) might return NULL due
330 * not to provide an implementation for get_string_at_offset(), so we
331 * try with the legacy implementation if that's the case. */
333 txt = get_text_for_legacy_implementations(text, offset,
334 (AtkTextGranularity) granularity,
335 &intstart_offset, &intend_offset);
337 startOffset = intstart_offset;
338 endOffset = intend_offset;
339 txt = validate_allocated_string (txt);
340 reply = dbus_message_new_method_return (message);
343 dbus_message_append_args (reply, DBUS_TYPE_STRING, &txt,
344 DBUS_TYPE_INT32, &startOffset,
345 DBUS_TYPE_INT32, &endOffset,
353 impl_GetAttributeValue (DBusConnection * bus, DBusMessage * message,
356 AtkText *text = (AtkText *) user_data;
359 dbus_int32_t startOffset, endOffset;
361 gint intstart_offset = 0, intend_offset = 0;
364 AtkAttributeSet *set;
368 g_return_val_if_fail (ATK_IS_TEXT (user_data),
369 droute_not_yet_handled_error (message));
370 if (!dbus_message_get_args
371 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_STRING,
372 &attributeName, DBUS_TYPE_INVALID))
374 return droute_invalid_arguments_error (message);
377 set = atk_text_get_run_attributes (text, offset,
378 &intstart_offset, &intend_offset);
379 startOffset = intstart_offset;
380 endOffset = intend_offset;
382 cur_attr = (GSList *) set;
385 at = (AtkAttribute *) cur_attr->data;
386 if (!strcmp (at->name, attributeName))
392 cur_attr = cur_attr->next;
396 reply = dbus_message_new_method_return (message);
399 dbus_message_append_args (reply, DBUS_TYPE_STRING, &rv, DBUS_TYPE_INT32,
400 &startOffset, DBUS_TYPE_INT32, &endOffset,
401 DBUS_TYPE_BOOLEAN, &defined,
404 atk_attribute_set_free (set);
409 impl_GetAttributes (DBusConnection * bus, DBusMessage * message,
412 AtkText *text = (AtkText *) user_data;
414 dbus_int32_t startOffset, endOffset;
415 gint intstart_offset, intend_offset;
417 AtkAttributeSet *set;
418 DBusMessageIter iter;
420 g_return_val_if_fail (ATK_IS_TEXT (user_data),
421 droute_not_yet_handled_error (message));
422 if (!dbus_message_get_args
423 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_INVALID))
425 return droute_invalid_arguments_error (message);
428 set = atk_text_get_run_attributes (text, offset,
429 &intstart_offset, &intend_offset);
431 startOffset = intstart_offset;
432 endOffset = intend_offset;
433 reply = dbus_message_new_method_return (message);
436 dbus_message_iter_init_append (reply, &iter);
437 spi_object_append_attribute_set (&iter, set);
438 dbus_message_append_args (reply, DBUS_TYPE_INT32, &startOffset,
439 DBUS_TYPE_INT32, &endOffset,
442 atk_attribute_set_free (set);
447 impl_GetDefaultAttributes (DBusConnection * bus, DBusMessage * message,
450 AtkText *text = (AtkText *) user_data;
452 AtkAttributeSet *set;
453 DBusMessageIter iter;
455 g_return_val_if_fail (ATK_IS_TEXT (user_data),
456 droute_not_yet_handled_error (message));
458 set = atk_text_get_default_attributes (text);
459 reply = dbus_message_new_method_return (message);
462 dbus_message_iter_init_append (reply, &iter);
463 spi_object_append_attribute_set (&iter, set);
465 atk_attribute_set_free (set);
470 impl_GetCharacterExtents (DBusConnection * bus, DBusMessage * message,
473 AtkText *text = (AtkText *) user_data;
475 dbus_uint32_t coordType;
476 dbus_int32_t x, y, width, height;
477 gint ix = 0, iy = 0, iw = 0, ih = 0;
480 g_return_val_if_fail (ATK_IS_TEXT (user_data),
481 droute_not_yet_handled_error (message));
482 if (!dbus_message_get_args
483 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_UINT32,
484 &coordType, DBUS_TYPE_INVALID))
486 return droute_invalid_arguments_error (message);
488 atk_text_get_character_extents (text, offset, &ix, &iy, &iw, &ih,
489 (AtkCoordType) coordType);
494 reply = dbus_message_new_method_return (message);
497 dbus_message_append_args (reply, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32,
498 &y, DBUS_TYPE_INT32, &width, DBUS_TYPE_INT32,
499 &height, DBUS_TYPE_INVALID);
505 impl_GetOffsetAtPoint (DBusConnection * bus, DBusMessage * message,
508 AtkText *text = (AtkText *) user_data;
510 dbus_uint32_t coordType;
514 g_return_val_if_fail (ATK_IS_TEXT (user_data),
515 droute_not_yet_handled_error (message));
516 if (!dbus_message_get_args
517 (message, NULL, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y,
518 DBUS_TYPE_UINT32, &coordType, DBUS_TYPE_INVALID))
520 return droute_invalid_arguments_error (message);
522 rv = atk_text_get_offset_at_point (text, x, y, coordType);
523 reply = dbus_message_new_method_return (message);
526 dbus_message_append_args (reply, DBUS_TYPE_INT32, &rv,
533 impl_GetNSelections (DBusConnection * bus, DBusMessage * message,
536 AtkText *text = (AtkText *) user_data;
540 g_return_val_if_fail (ATK_IS_TEXT (user_data),
541 droute_not_yet_handled_error (message));
542 rv = atk_text_get_n_selections (text);
543 reply = dbus_message_new_method_return (message);
546 dbus_message_append_args (reply, DBUS_TYPE_INT32, &rv,
553 impl_GetSelection (DBusConnection * bus, DBusMessage * message,
556 AtkText *text = (AtkText *) user_data;
557 dbus_int32_t selectionNum;
558 dbus_int32_t startOffset, endOffset;
559 gint intstart_offset = 0, intend_offset = 0;
562 g_return_val_if_fail (ATK_IS_TEXT (user_data),
563 droute_not_yet_handled_error (message));
564 if (!dbus_message_get_args
565 (message, NULL, DBUS_TYPE_INT32, &selectionNum, DBUS_TYPE_INVALID))
567 return droute_invalid_arguments_error (message);
569 /* atk_text_get_selection returns gchar * which we discard */
570 g_free (atk_text_get_selection
571 (text, selectionNum, &intstart_offset, &intend_offset));
572 startOffset = intstart_offset;
573 endOffset = intend_offset;
574 reply = dbus_message_new_method_return (message);
577 dbus_message_append_args (reply, DBUS_TYPE_INT32, &startOffset,
578 DBUS_TYPE_INT32, &endOffset,
585 impl_AddSelection (DBusConnection * bus, DBusMessage * message,
588 AtkText *text = (AtkText *) user_data;
589 dbus_int32_t startOffset, endOffset;
593 g_return_val_if_fail (ATK_IS_TEXT (user_data),
594 droute_not_yet_handled_error (message));
595 if (!dbus_message_get_args
596 (message, NULL, DBUS_TYPE_INT32, &startOffset, DBUS_TYPE_INT32,
597 &endOffset, DBUS_TYPE_INVALID))
599 return droute_invalid_arguments_error (message);
601 rv = atk_text_add_selection (text, startOffset, endOffset);
602 reply = dbus_message_new_method_return (message);
605 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
612 impl_RemoveSelection (DBusConnection * bus, DBusMessage * message,
615 AtkText *text = (AtkText *) user_data;
616 dbus_int32_t selectionNum;
620 g_return_val_if_fail (ATK_IS_TEXT (user_data),
621 droute_not_yet_handled_error (message));
622 if (!dbus_message_get_args
623 (message, NULL, DBUS_TYPE_INT32, &selectionNum, DBUS_TYPE_INVALID))
625 return droute_invalid_arguments_error (message);
627 rv = atk_text_remove_selection (text, selectionNum);
628 reply = dbus_message_new_method_return (message);
631 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
638 impl_SetSelection (DBusConnection * bus, DBusMessage * message,
641 AtkText *text = (AtkText *) user_data;
642 dbus_int32_t selectionNum, startOffset, endOffset;
646 g_return_val_if_fail (ATK_IS_TEXT (user_data),
647 droute_not_yet_handled_error (message));
648 if (!dbus_message_get_args
649 (message, NULL, DBUS_TYPE_INT32, &selectionNum, DBUS_TYPE_INT32,
650 &startOffset, DBUS_TYPE_INT32, &endOffset, DBUS_TYPE_INVALID))
652 return droute_invalid_arguments_error (message);
654 rv = atk_text_set_selection (text, selectionNum, startOffset, endOffset);
655 reply = dbus_message_new_method_return (message);
658 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
665 impl_GetRangeExtents (DBusConnection * bus, DBusMessage * message,
668 AtkText *text = (AtkText *) user_data;
669 dbus_int32_t startOffset, endOffset;
670 dbus_uint32_t coordType;
671 AtkTextRectangle rect;
672 dbus_int32_t x, y, width, height;
675 g_return_val_if_fail (ATK_IS_TEXT (user_data),
676 droute_not_yet_handled_error (message));
677 if (!dbus_message_get_args
678 (message, NULL, DBUS_TYPE_INT32, &startOffset, DBUS_TYPE_INT32,
679 &endOffset, DBUS_TYPE_UINT32, &coordType, DBUS_TYPE_INVALID))
681 return droute_invalid_arguments_error (message);
683 memset (&rect, 0, sizeof (rect));
684 atk_text_get_range_extents (text, startOffset, endOffset,
685 (AtkCoordType) coordType, &rect);
689 height = rect.height;
690 reply = dbus_message_new_method_return (message);
693 dbus_message_append_args (reply, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32,
694 &y, DBUS_TYPE_INT32, &width, DBUS_TYPE_INT32,
695 &height, DBUS_TYPE_INVALID);
700 #define MAXRANGELEN 512
703 impl_GetBoundedRanges (DBusConnection * bus, DBusMessage * message,
706 AtkText *text = (AtkText *) user_data;
707 dbus_int32_t x, y, width, height;
708 dbus_uint32_t coordType, xClipType, yClipType;
709 AtkTextRange **range_list = NULL;
710 AtkTextRectangle rect;
712 DBusMessageIter iter, array, struc, variant;
714 g_return_val_if_fail (ATK_IS_TEXT (user_data),
715 droute_not_yet_handled_error (message));
716 if (!dbus_message_get_args
717 (message, NULL, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y,
718 DBUS_TYPE_INT32, &height, DBUS_TYPE_INT32, &width, DBUS_TYPE_UINT32,
719 &coordType, DBUS_TYPE_UINT32, &xClipType, DBUS_TYPE_UINT32, &yClipType,
722 return droute_invalid_arguments_error (message);
727 rect.height = height;
730 atk_text_get_bounded_ranges (text, &rect, (AtkCoordType) coordType,
731 (AtkTextClipType) xClipType,
732 (AtkTextClipType) yClipType);
733 reply = dbus_message_new_method_return (message);
736 /* This isn't pleasant. */
737 dbus_message_iter_init_append (reply, &iter);
738 if (dbus_message_iter_open_container
739 (&iter, DBUS_TYPE_ARRAY, "(iisv)", &array))
742 int count = (range_list ? MAXRANGELEN : 0);
743 for (len = 0; len < count && range_list[len]; ++len)
745 if (dbus_message_iter_open_container
746 (&array, DBUS_TYPE_STRUCT, NULL, &struc))
749 val = range_list[len]->start_offset;
750 dbus_message_iter_append_basic (&struc, DBUS_TYPE_INT32, &val);
751 val = range_list[len]->end_offset;
752 dbus_message_iter_append_basic (&struc, DBUS_TYPE_INT32, &val);
753 dbus_message_iter_append_basic (&struc, DBUS_TYPE_STRING,
754 &range_list[len]->content);
755 /* The variant is unimplemented in atk, but I don't want to
756 * unilaterally muck with the spec and remove it, so I'll just
757 * throw in a dummy value */
758 if (dbus_message_iter_open_container
759 (&struc, DBUS_TYPE_VARIANT, "i", &variant))
761 dbus_uint32_t dummy = 0;
762 dbus_message_iter_append_basic (&variant, DBUS_TYPE_INT32,
764 dbus_message_iter_close_container (&struc, &variant);
766 dbus_message_iter_close_container (&array, &struc);
767 g_free (range_list[len]->content);
768 g_free (range_list[len]);
771 dbus_message_iter_close_container (&iter, &array);
781 impl_GetAttributeRun (DBusConnection * bus, DBusMessage * message,
784 AtkText *text = (AtkText *) user_data;
786 dbus_bool_t includeDefaults;
787 dbus_int32_t startOffset, endOffset;
788 gint intstart_offset = 0, intend_offset = 0;
790 AtkAttributeSet *attributes = NULL;
791 DBusMessageIter iter;
793 g_return_val_if_fail (ATK_IS_TEXT (user_data),
794 droute_not_yet_handled_error (message));
795 if (!dbus_message_get_args
796 (message, NULL, DBUS_TYPE_INT32, &offset, DBUS_TYPE_BOOLEAN,
797 &includeDefaults, DBUS_TYPE_INVALID))
799 return droute_invalid_arguments_error (message);
803 atk_text_get_run_attributes (text, offset, &intstart_offset,
808 attributes = g_slist_concat (attributes,
809 atk_text_get_default_attributes (text));
812 reply = dbus_message_new_method_return (message);
816 dbus_message_iter_init_append (reply, &iter);
817 spi_object_append_attribute_set (&iter, attributes);
819 startOffset = intstart_offset;
820 endOffset = intend_offset;
821 dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &startOffset);
822 dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &endOffset);
824 atk_attribute_set_free (attributes);
830 impl_GetDefaultAttributeSet (DBusConnection * bus, DBusMessage * message,
833 AtkText *text = (AtkText *) user_data;
835 DBusMessageIter iter;
836 AtkAttributeSet *attributes;
838 g_return_val_if_fail (ATK_IS_TEXT (user_data),
839 droute_not_yet_handled_error (message));
841 attributes = atk_text_get_default_attributes (text);
843 reply = dbus_message_new_method_return (message);
846 dbus_message_iter_init_append (reply, &iter);
847 spi_object_append_attribute_set (&iter, attributes);
851 atk_attribute_set_free (attributes);
856 static DRouteMethod methods[] = {
857 {impl_GetText, "GetText"},
858 {impl_SetCaretOffset, "SetCaretOffset"},
859 {impl_GetTextBeforeOffset, "GetTextBeforeOffset"},
860 {impl_GetTextAtOffset, "GetTextAtOffset"},
861 {impl_GetTextAfterOffset, "GetTextAfterOffset"},
862 {impl_GetStringAtOffset, "GetStringAtOffset"},
863 {impl_GetCharacterAtOffset, "GetCharacterAtOffset"},
864 {impl_GetAttributeValue, "GetAttributeValue"},
865 {impl_GetAttributes, "GetAttributes"},
866 {impl_GetDefaultAttributes, "GetDefaultAttributes"},
867 {impl_GetCharacterExtents, "GetCharacterExtents"},
868 {impl_GetOffsetAtPoint, "GetOffsetAtPoint"},
869 {impl_GetNSelections, "GetNSelections"},
870 {impl_GetSelection, "GetSelection"},
871 {impl_AddSelection, "AddSelection"},
872 {impl_RemoveSelection, "RemoveSelection"},
873 {impl_SetSelection, "SetSelection"},
874 {impl_GetRangeExtents, "GetRangeExtents"},
875 {impl_GetBoundedRanges, "GetBoundedRanges"},
876 {impl_GetAttributeRun, "GetAttributeRun"},
877 {impl_GetDefaultAttributeSet, "GetDefaultAttributeSet"},
881 static DRouteProperty properties[] = {
882 {impl_get_CharacterCount, NULL, "CharacterCount"},
883 {impl_get_CaretOffset, NULL, "CaretOffset"},
888 spi_initialize_text (DRoutePath * path)
890 spi_atk_add_interface (path,
891 ATSPI_DBUS_INTERFACE_TEXT, spi_org_a11y_atspi_Text, methods, properties);