GetNSelections has an out parameter, not an in
[platform/upstream/at-spi2-core.git] / atspi / atspi-text.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2002 Sun Microsystems Inc.,
6  * Copyright 2001, 2002 Ximian, Inc.
7  * Copyright 2010, 2011 Novell, Inc.
8  *
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.
13  *
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.
18  *
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.
23  */
24
25 #include "atspi-private.h"
26
27 AtspiRange *
28 atspi_range_copy (AtspiRange *src)
29 {
30   AtspiRange *dst = g_new (AtspiRange, 1);
31
32   if (dst)
33   {
34     dst->start_offset = src->start_offset;
35     dst->end_offset = src->end_offset;
36   }
37   return dst;
38 }
39
40 G_DEFINE_BOXED_TYPE (AtspiRange, atspi_range, atspi_range_copy, g_free)
41
42 static AtspiTextRange *
43 atspi_text_range_copy (AtspiTextRange *src)
44 {
45   AtspiTextRange *dst = g_new (AtspiTextRange, 1);
46
47   if (dst)
48   {
49     dst->content = g_strdup (src->content);
50     dst->start_offset = src->start_offset;
51     dst->end_offset = src->end_offset;
52   }
53   return dst;
54 }
55
56 static void
57 atspi_text_range_free (AtspiTextRange *range)
58 {
59   g_free (range->content);
60   g_free (range);
61 }
62
63 G_DEFINE_BOXED_TYPE (AtspiTextRange, atspi_text_range, atspi_text_range_copy,
64                      atspi_text_range_free)
65
66 /**
67  * atspi_text_get_character_count:
68  * @obj: a pointer to the #AtspiText object to query.
69  *
70  * Get the character count of an #AccessibleText object.
71  *
72  * Returns: a long integer indicating the total number of
73  *              characters in the #AccessibleText object.
74  **/
75 gint
76 atspi_text_get_character_count (AtspiText *obj, GError **error)
77 {
78   dbus_int32_t retval = 0;
79
80   g_return_val_if_fail (obj != NULL, -1);
81
82   _atspi_dbus_get_property (obj, atspi_interface_text, "CharacterCount", error, "i", &retval);
83
84   return retval;
85 }
86
87 /**
88  * atspi_text_get_text:
89  * @obj: a pointer to the #AtspiText object to query.
90  * @start_offset: a #long indicating the start of the desired text range.
91  * @end_offset: a #long indicating the first character past the desired range.
92  *
93  * Get a range of text from an #AtspiText object.  The number of bytes
94  *          in the returned string may exceed end_offset-start_offset, since
95  *          UTF-8 is a variable-width encoding.
96  *
97  * Returns: a text string containing characters from @start_offset
98  *          to @end_offset-1, inclusive, encoded as UTF-8.
99  **/
100 gchar *
101 atspi_text_get_text (AtspiText *obj,
102                         gint start_offset,
103                         gint end_offset,
104                         GError **error)
105 {
106   gchar *retval = NULL;
107   dbus_int32_t d_start_offset = start_offset, d_end_offset = end_offset;
108
109   g_return_val_if_fail (obj != NULL, g_strdup (""));
110
111   _atspi_dbus_call (obj, atspi_interface_text, "GetText", error, "ii=>s", d_start_offset, d_end_offset, &retval);
112
113   if (!retval)
114     retval = g_strdup ("");
115
116   return retval;
117 }
118
119 /**
120  * atspi_text_get_caret_offset:
121  * @obj: a pointer to the #AtspiText object to query.
122  *
123  * Get the current offset of the text caret in an #AtspiText object.
124  *
125  * Returns: a long integer indicating the current position of the text caret.
126  **/
127 gint
128 atspi_text_get_caret_offset (AtspiText *obj, GError **error)
129 {
130   dbus_int32_t retval = -1;
131
132   g_return_val_if_fail (obj != NULL, -1);
133
134   _atspi_dbus_get_property (obj, atspi_interface_text, "CaretOffset", error, "i", &retval);
135
136   return retval;
137 }
138
139 /**
140  * atspi_text_get_attributes:
141  * @obj: a pointer to the #AtspiText object to query.
142  * @offset: a long integer indicating the offset from which the attribute
143  *        search is based.
144  * @start_offset: (out): a #gint indicating the start of the desired text
145  *                range.
146  * @end_offset: (out): a #gint indicating the first character past the desired
147  *              range.
148  *
149  * Get the attributes applied to a range of text from an #AtspiText
150  *          object, and the bounds of the range.
151  *          The text attributes correspond to CSS attributes where possible,
152  *
153  * Returns: (element-type gchar* gchar*) (transfer full): a #GHashTable
154  *          describing the attributes at the given character offset
155  **/
156 GHashTable *
157 atspi_text_get_attributes (AtspiText *obj,
158                            gint offset,
159                            gint *start_offset,
160                            gint *end_offset,
161                            GError **error)
162 {
163   dbus_int32_t d_offset = offset;
164   dbus_int32_t d_start_offset, d_end_offset;
165   DBusMessage *reply;
166   DBusMessageIter iter;
167   GHashTable *ret = NULL;
168
169   if (obj == NULL)
170    return NULL;
171
172   reply = _atspi_dbus_call_partial (obj, atspi_interface_text, "GetAttributes", error, "i", d_offset);
173   _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}ii", error, ret)
174
175   dbus_message_iter_init (reply, &iter);
176   ret = _atspi_dbus_hash_from_iter (&iter);
177   dbus_message_iter_next (&iter);
178
179   dbus_message_iter_get_basic (&iter, &d_start_offset);
180   if (start_offset)
181     *start_offset = d_start_offset;
182   dbus_message_iter_next (&iter);
183   dbus_message_iter_get_basic (&iter, &d_end_offset);
184   if (end_offset)
185     *end_offset = d_start_offset;
186
187   dbus_message_unref (reply);
188   return ret;
189 }
190
191 /**
192  * atspi_text_get_attribute_run:
193  * @obj: a pointer to the #AtspiText object to query.
194  * @offset: an integer indicating the offset from which the attribute
195  *        search is based.
196  * @include_defaults: a #bool if False, the call should only return those 
197  *                 attributes which are explicitly set on the current attribute 
198  *                 run, omitting any attributes which are inherited from the 
199  *                 default values.
200  * @start_offset: (out): a #gint indicating the start of the desired text
201  *                range.
202  * @end_offset: (out): a #gint indicating the first character past the desired
203  *              range.
204  *
205  * Returns: (element-type gchar* gchar*) (transfer full): the AttributeSet
206  *          defined at offset, optionally including the 'default' attributes.
207  **/
208 GHashTable *
209 atspi_text_get_attribute_run (AtspiText *obj,
210                               gint offset,
211                               gboolean include_defaults,
212                               gint *start_offset,
213                               gint *end_offset,
214                               GError **error)
215 {
216   dbus_int32_t d_offset = offset;
217   dbus_int32_t d_start_offset, d_end_offset;
218   DBusMessage *reply;
219   DBusMessageIter iter;
220   GHashTable *ret = NULL;
221
222   if (obj == NULL)
223    return NULL;
224
225   reply = _atspi_dbus_call_partial (obj, atspi_interface_text,
226                                     "GetAttributeRun", error, "ib", d_offset,
227                                     include_defaults);
228   _ATSPI_DBUS_CHECK_SIG (reply, "a{ss}ii", error, ret)
229
230   dbus_message_iter_init (reply, &iter);
231   ret = _atspi_dbus_hash_from_iter (&iter);
232   dbus_message_iter_next (&iter);
233
234   dbus_message_iter_get_basic (&iter, &d_start_offset);
235   if (start_offset)
236     *start_offset = d_start_offset;
237   dbus_message_iter_next (&iter);
238   dbus_message_iter_get_basic (&iter, &d_end_offset);
239   if (end_offset)
240     *end_offset = d_end_offset;
241
242   dbus_message_unref (reply);
243   return ret;
244 }
245
246 /**
247  * atspi_text_get_attribute_value:
248  * @obj: a pointer to the #AtspiText object to query.
249  * @offset: The character offset at which to query the attribute.
250  * @attribute_name: The attribute to query.
251  *
252  * Returns: the value of a given attribute at the given offset, or NULL if
253  *          not present.
254  **/
255 gchar *
256 atspi_text_get_attribute_value (AtspiText *obj,
257                                 gint offset,
258                                 gchar *attribute_value,
259                                 GError **error)
260 {
261   gchar *retval = NULL;
262
263   g_return_val_if_fail (obj != NULL, NULL);
264
265   _atspi_dbus_call (obj, atspi_interface_text, "GetAttributeValue", error, "i=>s", offset, &retval);
266
267   return retval;
268 }
269
270 /**
271  * atspi_text_get_default_attributes:
272  * @obj: a pointer to the #AtspiText object to query.
273  *
274  * Get the default attributes applied to an #AtspiText
275  *          object.
276  *          The text attributes correspond to CSS attributes where possible,
277  *          keys and values are delimited from one another via ":", and
278  *          the delimiter between key/value pairs is ";". Thus
279  *          "font-size:10;foreground-color:0,0,0" would be a valid
280  *          return string.  The combination of this attribute set and
281  *          the attributes reported by #atspi_text_getAttributes
282  *          describes the entire set of text attributes over a range.
283  *
284  * Returns: (element-type gchar* gchar*) (transfer full): a #GHashTable
285  *          containing the default attributes applied to a text object,
286  *          (exclusive of explicitly-set attributes), encoded as UTF-8.
287  **/
288 GHashTable *
289 atspi_text_get_default_attributes (AtspiText *obj, GError **error)
290 {
291   DBusMessage *reply;
292
293     g_return_val_if_fail (obj != NULL, NULL);
294
295   reply = _atspi_dbus_call_partial (obj, atspi_interface_text, "GetDefaultAttributes", error, "");
296   return _atspi_dbus_return_hash_from_message (reply);
297 }
298
299
300 /**
301  * atspi_text_set_caret_offset:
302  * @obj: a pointer to the #AtspiText object on which to operate.
303  * @new_offset: the offset to which the text caret is to be moved.
304  *
305  * Set the text caret position for an #AtspiText object.
306  *
307  * Returns: #TRUE if successful, #FALSE otherwise.
308  **/
309 gboolean
310 atspi_text_set_caret_offset (AtspiText *obj,
311                                gint new_offset,
312                                GError **error)
313 {
314   dbus_int32_t d_new_offset = new_offset;
315   dbus_bool_t retval = FALSE;
316
317   g_return_val_if_fail (obj != NULL, FALSE);
318
319   _atspi_dbus_call (obj, atspi_interface_text, "SetCaretOffset", error, "i=>b", d_new_offset, &retval);
320
321   return retval;
322 }
323
324 /**
325  * atspi_text_get_text_before_offset:
326  * @obj: a pointer to the #AtspiText object on which to operate.
327  * @offset: an integer indicating the offset from which the delimiter
328  *        search is based.
329  * @type: an #AtspiTextBoundaryType indicating whether the desired
330  *       text string is a word, sentence, line, or attribute run.
331  *
332  * Get delimited text from an #AtspiText object which precedes a given
333  *          text offset.
334  *
335  * Returns: an #AtspiTextRange containing a UTF-8 string representing the
336  *          delimited text, both of whose delimiting boundaries are before the
337  *          current offset, or an empty string if no such text exists.
338  **/
339 AtspiTextRange *
340 atspi_text_get_text_before_offset (AtspiText *obj,
341                                     gint offset,
342                                     AtspiTextBoundaryType type,
343                                     GError **error)
344 {
345   dbus_int32_t d_offset = offset;
346   dbus_uint32_t d_type = type;
347   dbus_int32_t d_start_offset = -1, d_end_offset = -1;
348   AtspiTextRange *range = g_new0 (AtspiTextRange, 1);
349
350   if (range)
351     range->start_offset = range->end_offset = -1;
352   if (!obj || !range)
353     return range;
354
355   _atspi_dbus_call (obj, atspi_interface_text, "GetTextBeforeOffset", error,
356                     "iu=>sii", d_offset, d_type, &range->content,
357                     &d_start_offset, &d_end_offset);
358
359   range->start_offset = d_start_offset;
360   range->end_offset = d_end_offset;
361   if (!range->content)
362     range->content = g_strdup ("");
363
364   return range;
365 }
366
367 /**
368  * atspi_text_get_text_at_offset:
369  * @obj: a pointer to the #AtspiText object on which to operate.
370  * @offset: a long integer indicating the offset from which the delimiter
371  *        search is based.
372  * @type: an #AtspiTextBoundaryType indicating whether the desired
373  *       text string is a word, sentence, line, or attribute run.
374  *
375  * Get delimited text from an #AtspiText object which includes a given
376  *          text offset.
377  *
378  * Returns: an #AtspiTextRange containing a UTF-8 string representing the
379  *          delimited text, whose delimiting boundaries bracket the
380  *          current offset, or an empty string if no such text exists.
381  **/
382 AtspiTextRange *
383 atspi_text_get_text_at_offset (AtspiText *obj,
384                                     gint offset,
385                                     AtspiTextBoundaryType type,
386                                     GError **error)
387 {
388   dbus_int32_t d_offset = offset;
389   dbus_uint32_t d_type = type;
390   dbus_int32_t d_start_offset = -1, d_end_offset = -1;
391   AtspiTextRange *range = g_new0 (AtspiTextRange, 1);
392
393   if (range)
394     range->start_offset = range->end_offset = -1;
395   if (!obj || !range)
396     return range;
397
398   _atspi_dbus_call (obj, atspi_interface_text, "GetTextAtOffset", error,
399                     "iu=>sii", d_offset, d_type, &range->content,
400                     &d_start_offset, &d_end_offset);
401
402   range->start_offset = d_start_offset;
403   range->end_offset = d_end_offset;
404   if (!range->content)
405     range->content = g_strdup ("");
406
407   return range;
408 }
409
410 /**
411  * atspi_text_get_text_after_offset:
412  * @obj: a pointer to the #AtspiText object on which to operate.
413  * @offset: an integer indicating the offset from which the delimiter
414  *        search is based.
415  * @type: an #AtspiTextBoundaryType indicating whether the desired
416  *       text string is a word, sentence, line, or attribute run.
417  *
418  * Get delimited text from an #AtspiText object which follows a given
419  *          text offset.
420  *
421  * Returns: an #AtspiTextRange containing a UTF-8 string representing the
422  *          delimited text, both of whose delimiting boundaries are after or
423  *          inclusive of the current offset, or an empty string if no such
424  *          text exists.
425  **/
426 AtspiTextRange *
427 atspi_text_get_text_after_offset (AtspiText *obj,
428                                     gint offset,
429                                     AtspiTextBoundaryType type,
430                                     GError **error)
431 {
432   dbus_int32_t d_offset = offset;
433   dbus_uint32_t d_type = type;
434   dbus_int32_t d_start_offset = -1, d_end_offset = -1;
435   AtspiTextRange *range = g_new0 (AtspiTextRange, 1);
436
437   if (range)
438     range->start_offset = range->end_offset = -1;
439   if (!obj || !range)
440     return range;
441
442   _atspi_dbus_call (obj, atspi_interface_text, "GetTextAfterOffset", error,
443                     "iu=>sii", d_offset, d_type, &range->content,
444                     &d_start_offset, &d_end_offset);
445
446   range->start_offset = d_start_offset;
447   range->end_offset = d_end_offset;
448   if (!range->content)
449     range->content = g_strdup ("");
450
451   return range;
452 }
453
454 /**
455  * atspi_text_get_character_at_offset:
456  * @obj: a pointer to the #AtspiText object on which to operate.
457  * @offset: a long integer indicating the text offset where the desired
458  *          character is located.
459  *
460  * Get the character at a given offset for an #AtspiText object.
461  *
462  * Returns: an #unsigned long integer which represents the
463  *        UCS-4 unicode code point of the given character, or
464  *        0xFFFFFFFF if the character in question cannot be represented
465  *        in the UCS-4 encoding.
466  **/
467 guint
468 atspi_text_get_character_at_offset (AtspiText *obj,
469                                      gint offset,
470                                      GError **error)
471 {
472   dbus_int32_t d_offset = offset;
473   dbus_int32_t retval = -1;
474
475   g_return_val_if_fail (obj != NULL, -1);
476
477   _atspi_dbus_call (obj, atspi_interface_text, "GetCharacterAtOffset", error, "i=>i", d_offset, &retval);
478
479   return retval;
480 }
481
482 /**
483  * atspi_text_get_character_extents:
484  * @obj: a pointer to the #AtspiText object on which to operate.
485  * @offset: an integer indicating the offset of the text character for
486  *        whom boundary information is requested.
487  * @type: an #AccessibleCoordType indicating the coordinate system to use
488  *        for the returned values.
489  *
490  * Returns: A #AtspiRect specifying the position and size of the character.
491  *
492  * Get the bounding box containing the glyph representing
493  *        the character at a particular text offset.
494  **/
495 AtspiRect *
496 atspi_text_get_character_extents (AtspiText *obj,
497                                     gint offset,
498                                     AtspiCoordType type,
499                                     GError **error)
500 {
501   dbus_int32_t d_offset = offset;
502   dbus_uint32_t d_type = type;
503   dbus_int32_t d_x, d_y, d_width, d_height;
504   AtspiRect ret;
505
506   ret.x = ret.y = ret.width = ret.height = -1;
507
508   if (obj == NULL)
509     return atspi_rect_copy (&ret);
510
511   _atspi_dbus_call (obj, atspi_interface_text, "GetCharacterExtents", error, "iu=>iiii", d_offset, d_type, &d_x, &d_y, &d_width, &d_height);
512
513   ret.x = d_x;
514   ret.y = d_y;
515   ret.width = d_width;
516   ret.height = d_height;
517   return atspi_rect_copy (&ret);
518 }
519
520 /**
521  * atspi_text_get_offset_at_point:
522  * @obj: a pointer to the #AtspiText object on which to operate.
523  * @x: the x coordinate of the point to be queried.
524  * @y: the y coordinate of the point to be queried.
525  * @type: an #AtspiCoordType indicating the coordinate system in which
526  *       the values should be returned.
527  *
528  * Get the character offset into the text at a given point.
529  *
530  * Returns: the offset (as an integer) at the point (@x, @y)
531  *       in the specified coordinate system.
532  *
533  **/
534 gint
535 atspi_text_get_offset_at_point (AtspiText *obj,
536                                  gint x,
537                                  gint y,
538                                  AtspiCoordType type,
539                                  GError **error)
540 {
541   dbus_int32_t d_x = x, d_y = y;
542   dbus_uint32_t d_type = type;
543   dbus_int32_t retval = -1;
544
545   g_return_val_if_fail (obj != NULL, -1);
546
547   _atspi_dbus_call (obj, atspi_interface_text, "GetOffsetAtPoint", error, "iiu=>i", d_x, d_y, d_type, &retval);
548
549   return retval;
550 }
551
552 /**
553  * atspi_text_get_range_extents:
554  * @obj: a pointer to the #AtspiText object on which to operate.
555  * @start_offset: an integer indicating the offset of the first text character for
556  *        whom boundary information is requested.
557  * @end_offset: an integer indicating the offset of the text character
558  *        after the last character for whom boundary information is requested.
559  * @type: an #AtspiCoordType indicating the coordinate system to use
560  *        for the returned values.
561  *
562  * Returns: A #AtspiRect giving the position and size of the specified range
563  *          of text.
564  *
565  * Get the bounding box for text within a range in an  #AtspiText object.
566  **/
567 AtspiRect *
568 atspi_text_get_range_extents (AtspiText *obj,
569                                 gint start_offset,
570                                 gint end_offset,
571                                 AtspiCoordType type,
572                                 GError **error)
573 {
574   dbus_int32_t d_start_offset = start_offset, d_end_offset = end_offset;
575   dbus_uint32_t d_type = type;
576   dbus_int32_t d_x, d_y, d_width, d_height;
577   AtspiRect ret;
578
579   ret.x = ret.y = ret.width = ret.height = -1;
580
581   if (obj == NULL)
582     return atspi_rect_copy (&ret);
583
584   _atspi_dbus_call (obj, atspi_interface_text, "GetRangeExtents", error, "iiu=>iiii", d_start_offset, d_end_offset, d_type, &d_x, &d_y, &d_width, &d_height);
585
586   ret.x = d_x;
587   ret.y = d_y;
588   ret.width = d_width;
589   ret.height = d_height;
590   return atspi_rect_copy (&ret);
591 }
592
593 /**
594  * atspi_text_get_bounded_ranges:
595  * @obj: a pointer to the #AtspiText object on which to operate.
596  * @x: the 'starting' x coordinate of the bounding box.
597  * @y: the 'starting' y coordinate of the bounding box.
598  * @width: the x extent of the bounding box.
599  * @height: the y extent of the bounding box.
600  * @type: an #AccessibleCoordType indicating the coordinate system to use
601  *        for the returned values.
602  * @clipTypeX: an #AtspiTextClipType indicating how to treat characters that
603  *        intersect the bounding box's x extents.
604  * @clipTypeY: an #AtspiTextClipType indicating how to treat characters that
605  *        intersect the bounding box's y extents.
606  *
607  * Get the ranges of text from an #AtspiText object which lie within the
608  *          bounds defined by (@x, @y) and (@x+@width, @y+@height).
609  *
610  * Returns: (transfer full) (element-type AtspiTextRange*): a null-terminated list of
611  *          pointers to #AtspiTextRange structs detailing the bounded text.
612  **/
613 GArray *
614 atspi_text_get_bounded_ranges (AtspiText *obj,
615                                  gint x,
616                                  gint y,
617                                  gint width,
618                                  gint height,
619                                  AtspiCoordType type,
620                                  AtspiTextClipType clipTypeX,
621                                  AtspiTextClipType clipTypeY,
622                                  GError **error)
623 {
624   dbus_int32_t d_x = x, d_y = y, d_width = width, d_height = height;
625   dbus_uint32_t d_type = type;
626   dbus_uint32_t d_clipTypeX = clipTypeX, d_clipTypeY = clipTypeY;
627   GArray *range_seq;
628
629   g_return_val_if_fail (obj != NULL, NULL);
630
631   _atspi_dbus_call (obj, atspi_interface_text, "GetBoundedRanges", error, "iiiiuuu=>a(iisv)", d_x, d_y, d_width, d_height, d_type, d_clipTypeX, d_clipTypeY, &range_seq);
632
633   return range_seq;
634 }
635
636 /**
637  * atspi_text_get_n_selections:
638  * @obj: a pointer to the #AtspiText object on which to operate.
639  *
640  * Get the number of active non-contiguous selections for an
641  *          #AtspiText object.
642  *
643  * Returns: a long integer indicating the current
644  *          number of non-contiguous text selections active
645  *          within an #AtspiText object.
646  **/
647 gint
648 atspi_text_get_n_selections (AtspiText *obj, GError **error)
649 {
650   dbus_int32_t retval = 0;
651
652   g_return_val_if_fail (obj != NULL, -1);
653
654   _atspi_dbus_call (obj, atspi_interface_text, "GetNSelections", error, "=>i", &retval);
655
656   return retval;
657 }
658
659 /**
660  * atspi_text_get_sSelection:
661  * @obj: a pointer to the #AtspiText object on which to operate.
662  * @selection_num: an integer indicating which selection to query.
663  * @start_offset: a pointer to a long integer into which the start offset
664  *           of the selection will be returned.
665  * @end_offset: a pointer to a long integer into which the start offset
666  *           of the selection will be returned.
667  *
668  * Get the bounds of the @selection_num-th active text selection for an
669  *         #AtspiText object.
670  **/
671 AtspiRange *
672 atspi_text_get_selection (AtspiText *obj,
673                              gint selection_num,
674                              GError **error)
675 {
676   dbus_int32_t d_selection_num = selection_num;
677   dbus_int32_t d_start_offset, d_end_offset;
678   AtspiRange *ret = g_new (AtspiRange, 1);
679
680   if (ret)
681     ret->start_offset = ret->end_offset = -1;
682
683   if (!obj || !ret)
684     return ret;
685
686   _atspi_dbus_call (obj, atspi_interface_text, "GetSelection", error, "i=>ii", d_selection_num, &d_start_offset, &d_end_offset);
687
688   ret->start_offset = d_start_offset;
689   ret->end_offset = d_end_offset;
690   return ret;
691 }
692
693 /**
694  * atspi_text_add_selection:
695  * @obj: a pointer to the #AtspiText object on which to operate.
696  * @start_offset: the starting offset of the desired new selection.
697  * @end_offset: the offset of the first character after the new selection.
698  *
699  * Select some text (add a text selection) in an #AtspiText object.
700  *
701  * Returns: #TRUE if successful, #FALSE otherwise.
702  **/
703 gboolean
704 atspi_text_add_selection (AtspiText *obj,
705                              gint start_offset, gint end_offset,
706                              GError **error)
707 {
708   dbus_int32_t d_start_offset = start_offset, d_end_offset = end_offset;
709   dbus_bool_t retval = FALSE;
710
711   _atspi_dbus_call (obj, atspi_interface_text, "AddSelection", error, "ii=>b", d_start_offset, d_end_offset, &retval);
712
713   return retval;
714 }
715
716 /**
717  * atspi_text_remove_selection:
718  * @obj: a pointer to the #AtspiText object on which to operate.
719  * @selection_num: an integer indicating which (possibly of several)
720  *         text selection to remove.
721  *
722  * De-select a text selection.
723  *
724  * Returns: #TRUE if successful, #FALSE otherwise.
725  **/
726 gboolean
727 atspi_text_remove_selection (AtspiText *obj,
728                                 gint selection_num,
729                                 GError **error)
730 {
731   dbus_int32_t d_selection_num = selection_num;
732   dbus_bool_t retval = FALSE;
733
734   g_return_val_if_fail (obj != NULL, FALSE);
735
736   _atspi_dbus_call (obj, atspi_interface_text, "RemoveSelection", error, "i=>b", d_selection_num, &retval);
737
738   return retval;
739 }
740
741 /**
742  * atspi_text_set_selection:
743  * @obj: a pointer to the #AtspiText object on which to operate.
744  * @selection_num: a zero-offset index indicating which text selection to modify.
745  * @start_offset: a long int, the new starting offset for the selection.
746  * @end_offset: a long int, the desired new offset of the first character
747  *             after the selection.
748  *
749  * Change the bounds of an existing #AtspiText text selection.
750  *
751  * Returns: #TRUE if successful, #FALSE otherwise.
752  **/
753 gboolean
754 atspi_text_set_selection (AtspiText *obj,
755                              gint selection_num,
756                              gint start_offset,
757                              gint end_offset,
758                              GError **error)
759 {
760   dbus_int32_t d_selection_num = selection_num, d_start_offset = start_offset, d_end_offset = end_offset;
761   dbus_bool_t retval = FALSE;
762
763   g_return_val_if_fail (obj != NULL, FALSE);
764
765   _atspi_dbus_call (obj, atspi_interface_text, "SetSelection", error, "iii=>b", d_selection_num, d_start_offset, d_end_offset, &retval);
766
767   return retval;
768 }
769
770 static void
771 atspi_text_base_init (AtspiText *klass)
772 {
773 }
774
775 GType
776 atspi_text_get_type (void)
777 {
778   static GType type = 0;
779
780   if (!type) {
781     static const GTypeInfo tinfo =
782     {
783       sizeof (AtspiText),
784       (GBaseInitFunc) atspi_text_base_init,
785       (GBaseFinalizeFunc) NULL,
786     };
787
788     type = g_type_register_static (G_TYPE_INTERFACE, "AtspiText", &tinfo, 0);
789
790   }
791   return type;
792 }