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