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