2002-12-16 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / cspi / spi_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 <cspi/spi-private.h>
25
26 static Accessibility_TEXT_BOUNDARY_TYPE
27 get_accessible_text_boundary_type (AccessibleTextBoundaryType type)
28 {
29   switch (type)
30     {
31     case SPI_TEXT_BOUNDARY_CHAR:
32       return Accessibility_TEXT_BOUNDARY_CHAR;
33       break;
34     case SPI_TEXT_BOUNDARY_CURSOR_POS:
35       /* FixME */
36       return Accessibility_TEXT_BOUNDARY_CHAR;
37       break;
38     case SPI_TEXT_BOUNDARY_WORD_START:
39       return Accessibility_TEXT_BOUNDARY_WORD_START;
40       break;
41     case SPI_TEXT_BOUNDARY_WORD_END:
42       return Accessibility_TEXT_BOUNDARY_WORD_END;
43       break;
44     case SPI_TEXT_BOUNDARY_SENTENCE_START:
45       return Accessibility_TEXT_BOUNDARY_SENTENCE_START;
46       break;
47     case SPI_TEXT_BOUNDARY_SENTENCE_END:
48       return Accessibility_TEXT_BOUNDARY_SENTENCE_END;
49       break;
50     case SPI_TEXT_BOUNDARY_LINE_START:
51       return Accessibility_TEXT_BOUNDARY_LINE_START;
52       break;
53     case SPI_TEXT_BOUNDARY_LINE_END:
54       return Accessibility_TEXT_BOUNDARY_LINE_END;
55       break;
56     case SPI_TEXT_BOUNDARY_ATTRIBUTE_RANGE:
57       /* Fixme */
58       return Accessibility_TEXT_BOUNDARY_CHAR;
59       break;
60     }
61   /* FIXME */
62   return Accessibility_TEXT_BOUNDARY_CHAR;
63 }
64
65
66 /**
67  * AccessibleText_ref:
68  * @obj: a pointer to the #AccessibleText object on which to operate.
69  *
70  * Increment the reference count for an #AccessibleText object.
71  **/
72 void
73 AccessibleText_ref (AccessibleText *obj)
74 {
75   cspi_object_ref (obj);
76 }
77
78 /**
79  * AccessibleText_unref:
80  * @obj: a pointer to the #Accessible object on which to operate.
81  *
82  * Decrement the reference count for an #AccessibleText object.
83  **/
84 void
85 AccessibleText_unref (AccessibleText *obj)
86 {
87   cspi_object_unref (obj);
88 }
89
90 /**
91  * AccessibleText_getCharacterCount:
92  * @obj: a pointer to the #AccessibleText 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 long
100 AccessibleText_getCharacterCount (AccessibleText *obj)
101 {
102   long retval;
103
104   cspi_return_val_if_fail (obj != NULL, -1);
105
106   retval = Accessibility_Text__get_characterCount (CSPI_OBJREF (obj), cspi_ev ());
107
108   cspi_return_val_if_ev ("getCharacterCount", -1);
109
110   return retval;
111 }
112
113 /**
114  * AccessibleText_getText:
115  * @obj: a pointer to the #AccessibleText object to query.
116  * @startOffset: a #long indicating the start of the desired text range.
117  * @endOffset: a #long indicating the first character past the desired range.
118  *
119  * Get a range of text from an #AccessibleText object.  The number of bytes
120  *          in the returned string may exceed endOffset-startOffset, since
121  *          UTF-8 is a variable-width encoding.
122  *
123  * Returns: a text string containing characters from @startOffset
124  *          to @endOffset-1, inclusive, encoded as UTF-8.
125  **/
126 char *
127 AccessibleText_getText (AccessibleText *obj,
128                         long int startOffset,
129                         long int endOffset)
130 {
131   char *retval;
132
133   cspi_return_val_if_fail (obj != NULL, NULL);
134
135   retval =
136     Accessibility_Text_getText (CSPI_OBJREF (obj),
137                                 startOffset,
138                                 endOffset,
139                                 cspi_ev ());
140
141   cspi_return_val_if_ev ("getText", NULL);
142
143   return retval;
144 }
145
146 /**
147  * AccessibleText_getCaretOffset:
148  * @obj: a pointer to the #AccessibleText object to query.
149  *
150  * Get the current offset of the text caret in an #AccessibleText object.
151  *
152  * Returns: a long integer indicating the current position of the text caret.
153  **/
154 long
155 AccessibleText_getCaretOffset (AccessibleText *obj)
156 {
157   long retval;
158
159   cspi_return_val_if_fail (obj != NULL, -1);
160
161   retval =
162     Accessibility_Text__get_caretOffset (CSPI_OBJREF (obj), cspi_ev ());
163
164   cspi_return_val_if_ev ("getCaretOffset", -1);
165
166   return retval;
167 }
168
169 /**
170  * AccessibleText_getAttributes:
171  * @obj: a pointer to the #AccessibleText object to query.
172  * @offset: a long integer indicating the offset from which the attribute
173  *        search is based.
174  * @startOffset: a #long indicating the start of the desired text range.
175  * @endOffset: a #long indicating the first character past the desired range.
176  *
177  * Get the attributes applied to a range of text from an #AccessibleText
178  *          object, and the bounds of the range.
179  *          The text attributes correspond to CSS attributes where possible,
180  *          keys and values are delimited from one another via ":", and
181  *          the delimiter between key/value pairs is ";". Thus 
182  *          "font-size:10;foreground-color:0,0,0" would be a valid
183  *          return string.
184  *
185  * Returns: a text string describing the attributes occurring within the
186  *          attribute run containing @offset, encoded as UTF-8.
187  **/
188 char *
189 AccessibleText_getAttributes (AccessibleText *obj,
190                               long int offset,
191                               long int *startOffset,
192                               long int *endOffset)
193 {
194   CORBA_long retStartOffset, retEndOffset;
195   char *retval; 
196
197   if (obj == NULL)
198     {
199       *startOffset = *endOffset = -1;
200       return NULL;
201     }
202
203   retval = Accessibility_Text_getAttributes (CSPI_OBJREF (obj),
204                                       offset,
205                                       &retStartOffset,
206                                       &retEndOffset,
207                                       cspi_ev ());
208
209   if (!cspi_check_ev ("getAttributes"))
210     {
211       *startOffset = *endOffset = -1;
212       retval = NULL;
213     }
214   else
215     {
216       *startOffset = retStartOffset;
217       *endOffset   = retEndOffset;
218     }
219
220   return retval;
221 }
222
223 /**
224  * AccessibleText_setCaretOffset:
225  * @obj: a pointer to the #AccessibleText object on which to operate.
226  * @newOffset: the offset to which the text caret is to be moved.
227  *
228  * Set the text caret position for an #AccessibleText object.
229  *
230  * Returns: #TRUE if successful, #FALSE otherwise.
231  **/
232 SPIBoolean
233 AccessibleText_setCaretOffset (AccessibleText *obj,
234                                long int newOffset)
235 {
236   SPIBoolean retval;
237
238   cspi_return_val_if_fail (obj != NULL, FALSE);
239
240   retval =
241     Accessibility_Text_setCaretOffset (CSPI_OBJREF (obj),
242                                        newOffset, cspi_ev ());
243
244   cspi_return_val_if_ev ("setCaretOffset", FALSE);
245
246   return retval;
247 }
248
249 /**
250  * AccessibleText_getTextBeforeOffset:
251  * @obj: a pointer to the #AccessibleText object on which to operate.
252  * @offset: a long integer indicating the offset from which the delimiter
253  *        search is based.
254  * @type: an #AccessibleTextBoundaryType indicating whether the desired
255  *       text string is a word, sentence, line, or attribute run.
256  * @startOffset: a pointer to a long integer which is assigned the
257  *       starting offset of the returned string, relative to the
258  *       original #AccessibleText.
259  * @endOffset: a pointer to a long integer which is assigned the
260  *       ending offset of the returned string, relative to the original
261  *       #AccessibleText.
262  *
263  * Get delimited text from an #AccessibleText object which precedes a given
264  *          text offset.
265  *
266  * Returns: a UTF-8 string representing the delimited text, both of whose
267  *          delimiting boundaries are before the current offset, or
268  *          an empty string if no such text exists.
269  **/
270 char *
271 AccessibleText_getTextBeforeOffset (AccessibleText *obj,
272                                     long int offset,
273                                     AccessibleTextBoundaryType type,
274                                     long int *startOffset,
275                                     long int *endOffset)
276 {
277   char *retval;
278   CORBA_long retStartOffset, retEndOffset;
279
280   if (obj == NULL)
281     {
282       *startOffset = *endOffset = -1;
283       return NULL;
284     }
285
286   retval = Accessibility_Text_getTextBeforeOffset (CSPI_OBJREF (obj),
287                                            offset,
288                         get_accessible_text_boundary_type (type),
289                                            &retStartOffset, &retEndOffset,
290                                            cspi_ev ());
291   if (!cspi_check_ev ("getTextBeforeOffset"))
292     {
293       *startOffset = *endOffset = -1;
294       retval = NULL;
295     }
296   else
297     {
298       *startOffset = retStartOffset;
299       *endOffset = retEndOffset;
300     }
301   return retval;
302 }
303
304 /**
305  * AccessibleText_getTextAtOffset:
306  * @obj: a pointer to the #AccessibleText object on which to operate.
307  * @offset: a long integer indicating the offset from which the delimiter
308  *        search is based.
309  * @type: an #AccessibleTextBoundaryType indicating whether the desired
310  *       text string is a word, sentence, line, or attribute run.
311  * @startOffset: a pointer to a long integer which is assigned the
312  *       starting offset of the returned string, relative to the
313  *       original #AccessibleText.
314  * @endOffset: a pointer to a long integer which is assigned the
315  *       ending offset of the returned string, relative to the original
316  *       #AccessibleText.
317  *
318  * Get delimited text from an #AccessibleText object which includes a given
319  *          text offset.
320  *
321  * Returns: a UTF-8 string representing the delimited text, whose
322  *          delimiting boundaries bracket the current offset, or
323  *          an empty string if no such text exists.
324  **/
325 char *
326 AccessibleText_getTextAtOffset (AccessibleText *obj,
327                                 long int offset,
328                                 AccessibleTextBoundaryType type,
329                                 long int *startOffset, long int *endOffset)
330 {
331   CORBA_long corbaStartOffset;
332   CORBA_long corbaEndOffset;
333   char      *retval;
334
335   if (obj == NULL)
336     {
337       *startOffset = *endOffset = -1;
338       return NULL;
339     }
340
341   retval = Accessibility_Text_getTextAtOffset (CSPI_OBJREF (obj),
342                                                offset,
343                           get_accessible_text_boundary_type (type),
344                                                &corbaStartOffset,
345                                                &corbaEndOffset,
346                                                cspi_ev ());
347
348   if (!cspi_check_ev ("getTextAtOffset"))
349     {
350       *startOffset = *endOffset = -1;
351       retval = NULL;
352     }
353   else
354     {
355       *startOffset = corbaStartOffset;
356       *endOffset   = corbaEndOffset;
357     }
358   return retval;
359 }
360
361 /**
362  * AccessibleText_getTextAfterOffset:
363  * @obj: a pointer to the #AccessibleText object on which to operate.
364  * @offset: a long integer indicating the offset from which the delimiter
365  *        search is based.
366  * @type: an #AccessibleTextBoundaryType indicating whether the desired
367  *       text string is a word, sentence, line, or attribute run.
368  * @startOffset: a pointer to a long integer which is assigned the
369  *       starting offset of the returned string, relative to the
370  *       original #AccessibleText.
371  * @endOffset: a pointer to a long integer which is assigned the
372  *       ending offset of the returned string, relative to the original
373  *       #AccessibleText.
374  *
375  * Get delimited text from an #AccessibleText object which follows a given
376  *          text offset.
377  *
378  * Returns: a UTF-8 string representing the delimited text, both of whose
379  *          delimiting boundaries are after or inclusive of the current
380  *          offset, or an empty string if no such text exists.
381  **/
382 char *
383 AccessibleText_getTextAfterOffset (AccessibleText *obj,
384                                    long int offset,
385                                    AccessibleTextBoundaryType type,
386                                    long int *startOffset, long int *endOffset)
387 {
388   char *retval;
389   CORBA_long retStartOffset, retEndOffset;
390
391   if (obj == NULL)
392     {
393       *startOffset = *endOffset = -1;
394       return NULL;
395     }
396
397   retval = Accessibility_Text_getTextAfterOffset (CSPI_OBJREF (obj),
398                                            offset,
399                              get_accessible_text_boundary_type (type),
400                                            &retStartOffset, &retEndOffset,
401                                            cspi_ev ());
402
403   if (!cspi_check_ev ("getTextAfterOffset"))
404     {
405       *startOffset = *endOffset = -1;
406       retval = NULL;
407     }
408   else
409     {
410       *startOffset = retStartOffset;
411       *endOffset   = retEndOffset;
412     }
413   return retval;
414 }
415
416 /**
417  * AccessibleText_getCharacterAtOffset:
418  * @obj: a pointer to the #AccessibleText object on which to operate.
419  * @offset: a long integer indicating the text offset where the desired
420  *          character is located.
421  *
422  * Get the character at a given offset for an #AccessibleText object.
423  *
424  * Returns: an #unsigned long integer which represents the
425  *        UCS-4 unicode code point of the given character, or
426  *        0xFFFFFFFF if the character in question cannot be represented
427  *        in the UCS-4 encoding.
428  **/
429 unsigned long
430 AccessibleText_getCharacterAtOffset (AccessibleText *obj,
431                                      long int offset)
432 {
433   long retval;
434
435   cspi_return_val_if_fail (obj != NULL, -1);
436
437   retval =
438     Accessibility_Text_getCharacterAtOffset (CSPI_OBJREF (obj),
439                                              offset,
440                                              cspi_ev ());
441
442   cspi_return_val_if_ev ("getCharacterAtOffset", -1);
443
444   return retval;
445 }
446
447 /**
448  * AccessibleText_getCharacterExtents:
449  * @obj: a pointer to the #AccessibleText object on which to operate.
450  * @offset: an integer indicating the offset of the text character for
451  *        whom boundary information is requested.
452  * @x: a pointer to a long integer into which the nominal x coordinate
453  *     of the corresponding glyph will be returned.
454  * @y:a pointer to a long integer into which the nominal y coordinate
455  *     of the corresponding glyph will be returned.
456  * @width:a pointer to a long integer into which the width
457  *     of the corresponding glyph will be returned.
458  * @height: a pointer to a long integer into which the height
459  *     of the corresponding glyph will be returned.
460  * @type: an #AccessibleCoordType indicating the coordinate system to use
461  *        for the returned values.
462  *
463  * Get the bounding box containing the glyph representing
464  *        the character at a particular text offset.
465  **/
466 void
467 AccessibleText_getCharacterExtents (AccessibleText *obj,
468                                     long int offset,
469                                     long int *x,
470                                     long int *y,
471                                     long int *width,
472                                     long int *height,
473                                     AccessibleCoordType type)
474 {
475   CORBA_long retX, retY, retWidth, retHeight;
476
477   if (obj == NULL)
478     {
479       *x = *y = -1;
480       *width = *height = -1;
481       return;
482     }
483
484   Accessibility_Text_getCharacterExtents (CSPI_OBJREF (obj),
485                                           offset,
486                                           &retX,
487                                           &retY,
488                                           &retWidth,
489                                           &retHeight,
490                                           type, cspi_ev ());
491
492   if (!cspi_check_ev ("getCharacterExtents"))
493     {
494       *x = *y = -1;
495       *width = *height = -1;
496     }
497   else
498     {
499       *x = retX;
500       *y = retY;
501       *width = retWidth;
502       *height = retHeight;
503     }
504 }
505
506 /**
507  * AccessibleText_getOffsetAtPoint:
508  * @obj: a pointer to the #AccessibleText object on which to operate.
509  * @x: the x coordinate of the point to be queried.
510  * @y: the y coordinate of the point to be queried.
511  * @type: an #AccessibleCoordType indicating the coordinate system in which
512  *       the values should be returned.
513  *
514  * Get the bounding box for a glyph at a certain #AccessibleText offset.
515  *
516  * Returns: the offset (as a long integer) at the point (@x, @y)
517  *       in the specified coordinate system.
518  *
519  **/
520 long
521 AccessibleText_getOffsetAtPoint (AccessibleText *obj,
522                                  long int x,
523                                  long int y,
524                                  AccessibleCoordType type)
525 {
526   long retval;
527
528   cspi_return_val_if_fail (obj != NULL, -1);
529
530   retval =
531     Accessibility_Text_getOffsetAtPoint (CSPI_OBJREF (obj),
532                                          x,
533                                          y,
534                                          type, cspi_ev ());
535
536   cspi_return_val_if_ev ("getOffsetAtPoint", -1);
537
538   return retval;
539 }
540
541 /**
542  * AccessibleText_getNSelections:
543  * @obj: a pointer to the #AccessibleText object on which to operate.
544  *
545  * Get the number of active non-contiguous selections for an
546  *          #AccessibleText object.
547  *
548  * Returns: a long integer indicating the current
549  *          number of non-contiguous text selections active
550  *          within an #AccessibleText object.
551  **/
552 long
553 AccessibleText_getNSelections (AccessibleText *obj)
554 {
555   long retval;
556
557   cspi_return_val_if_fail (obj != NULL, -1);
558
559   retval =
560     Accessibility_Text_getNSelections (CSPI_OBJREF (obj), cspi_ev ());
561
562   cspi_return_val_if_ev ("getNSelections", -1);
563
564   return retval;
565 }
566
567 /**
568  * AccessibleText_getSelection:
569  * @obj: a pointer to the #AccessibleText object on which to operate.
570  * @selectionNum: an integer indicating which selection to query.
571  * @startOffset: a pointer to a long integer into which the start offset
572  *           of the selection will be returned.
573  * @endOffset: a pointer to a long integer into which the start offset
574  *           of the selection will be returned.
575  *
576  * Get the bounds of the @selectionNum-th active text selection for an
577  *         #AccessibleText object.
578  **/
579 void
580 AccessibleText_getSelection (AccessibleText *obj,
581                              long int selectionNum,
582                              long int *startOffset,
583                              long int *endOffset)
584 {
585   CORBA_long retStartOffset, retEndOffset;
586
587   if (obj == NULL)
588     {
589       *endOffset = *startOffset = -1;
590       return;
591     }
592
593   Accessibility_Text_getSelection (CSPI_OBJREF (obj),
594                                    selectionNum,
595                                    &retStartOffset, &retEndOffset,
596                                    cspi_ev ());
597
598   if (!cspi_check_ev ("getSelection"))
599     {
600       *startOffset = *endOffset = -1;
601     }
602   else
603     {
604       *startOffset = retStartOffset;
605       *endOffset   = retEndOffset;
606     }
607 }
608
609 /**
610  * AccessibleText_addSelection:
611  * @obj: a pointer to the #AccessibleText object on which to operate.
612  * @startOffset: the starting offset of the desired new selection.
613  * @endOffset: the offset of the first character after the new selection.
614  *
615  * Select some text (add a text selection) in an #AccessibleText object.
616  *
617  * Returns: #TRUE if successful, #FALSE otherwise.
618  **/
619 SPIBoolean
620 AccessibleText_addSelection (AccessibleText *obj,
621                              long int startOffset, long int endOffset)
622 {
623   SPIBoolean retval;
624
625   cspi_return_val_if_fail (obj != NULL, FALSE);
626
627   retval =
628     Accessibility_Text_addSelection (
629       CSPI_OBJREF (obj), startOffset,
630       endOffset, cspi_ev ());
631
632   cspi_return_val_if_ev ("addSelection", FALSE);
633
634   return retval;
635 }
636
637 /**
638  * AccessibleText_removeSelection:
639  * @obj: a pointer to the #AccessibleText object on which to operate.
640  * @selectionNum: an integer indicating which (possibly of several)
641  *         text selection to remove.
642  *
643  * De-select a text selection.
644  *
645  * Returns: #TRUE if successful, #FALSE otherwise.
646  **/
647 SPIBoolean
648 AccessibleText_removeSelection (AccessibleText *obj,
649                                 long int selectionNum)
650 {
651   SPIBoolean retval;
652
653   cspi_return_val_if_fail (obj != NULL, FALSE);
654
655   retval =
656     Accessibility_Text_removeSelection (
657       CSPI_OBJREF (obj), selectionNum, cspi_ev ());
658
659   cspi_return_val_if_ev ("removeSelection", FALSE);
660
661   return retval;
662 }
663
664 /**
665  * AccessibleText_setSelection:
666  * @obj: a pointer to the #AccessibleText object on which to operate.
667  * @selectionNum: a zero-offset index indicating which text selection to modify.
668  * @startOffset: a long int, the new starting offset for the selection.
669  * @endOffset: a long int, the desired new offset of the first character
670  *             after the selection.
671  *
672  * Change the bounds of an existing #AccessibleText text selection.
673  *
674  * Returns: #TRUE if successful, #FALSE otherwise.
675  **/
676 SPIBoolean
677 AccessibleText_setSelection (AccessibleText *obj,
678                              long int selectionNum,
679                              long int startOffset,
680                              long int endOffset)
681 {
682   SPIBoolean retval;
683
684   cspi_return_val_if_fail (obj != NULL, FALSE);
685
686   retval = Accessibility_Text_setSelection (CSPI_OBJREF (obj),
687                                    selectionNum,
688                                    startOffset,
689                                    endOffset, cspi_ev ());
690
691   cspi_return_val_if_ev ("setSelection", FALSE);
692
693   return retval;
694 }
695
696
697