2001-11-20 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / libspi / 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 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* text.c : implements the Text interface */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <libspi/text.h>
29
30 /* Our parent Gtk object type */
31 #define PARENT_TYPE BONOBO_TYPE_OBJECT
32
33 /* A pointer to our parent object class */
34 static GObjectClass *spi_text_parent_class;
35
36 /* Static function declarations */
37
38 static void
39 accessibility_text_class_init (SpiTextClass *klass);
40
41 static void
42 accessibility_text_init (SpiText *text);
43
44 static void
45 accessibility_text_object_finalize (GObject *obj);
46
47 static CORBA_string
48 impl_getText (PortableServer_Servant _servant,
49               const CORBA_long startOffset,
50               const CORBA_long endOffset,
51               CORBA_Environment * ev);
52
53 static CORBA_string
54 impl_getTextAfterOffset (PortableServer_Servant _servant,
55                          const CORBA_long offset,
56                          const
57                          Accessibility_TEXT_BOUNDARY_TYPE
58                          type, CORBA_long * startOffset,
59                          CORBA_long * endOffset,
60                          CORBA_Environment * ev);
61 static CORBA_string
62 impl_getTextAtOffset (PortableServer_Servant _servant,
63                       const CORBA_long offset,
64                       const Accessibility_TEXT_BOUNDARY_TYPE type,
65                       CORBA_long * startOffset,
66                       CORBA_long * endOffset,
67                       CORBA_Environment * ev);
68
69 static CORBA_unsigned_long
70 impl_getCharacterAtOffset (PortableServer_Servant _servant,
71                            const CORBA_long offset,
72                            CORBA_Environment * ev);
73
74 static CORBA_string
75 impl_getTextBeforeOffset (PortableServer_Servant _servant,
76                           const CORBA_long offset,
77                           const
78                           Accessibility_TEXT_BOUNDARY_TYPE
79                           type, CORBA_long * startOffset,
80                           CORBA_long * endOffset,
81                           CORBA_Environment * ev);
82
83 static CORBA_long
84 impl__get_caretOffset (PortableServer_Servant _servant,
85                      CORBA_Environment * ev);
86
87 static CORBA_string
88 impl_getAttributes (PortableServer_Servant _servant,
89                        const CORBA_long offset,
90                        CORBA_long * startOffset,
91                        CORBA_long * endOffset,
92                        CORBA_Environment * ev);
93
94 static void 
95 impl_getCharacterExtents (PortableServer_Servant _servant,
96                           const CORBA_long offset, CORBA_long * x,
97                           CORBA_long * y, CORBA_long * width,
98                           CORBA_long * height,
99                           const CORBA_short coordType,
100                           CORBA_Environment * ev);
101
102 static CORBA_long
103 impl__get_characterCount (PortableServer_Servant _servant,
104                         CORBA_Environment * ev);
105
106 static CORBA_long
107 impl_getOffsetAtPoint (PortableServer_Servant _servant,
108                        const CORBA_long x, const CORBA_long y,
109                        const CORBA_short coordType,
110                        CORBA_Environment * ev);
111
112 static CORBA_long
113 impl_getNSelections (PortableServer_Servant _servant,
114                      CORBA_Environment * ev);
115
116 static void 
117 impl_getSelection (PortableServer_Servant _servant,
118                    const CORBA_long selectionNum,
119                    CORBA_long * startOffset, CORBA_long * endOffset,
120                    CORBA_Environment * ev);
121
122 static CORBA_boolean
123 impl_addSelection (PortableServer_Servant _servant,
124                    const CORBA_long startOffset,
125                    const CORBA_long endOffset,
126                    CORBA_Environment * ev);
127
128 static CORBA_boolean
129 impl_removeSelection (PortableServer_Servant _servant,
130                       const CORBA_long selectionNum,
131                       CORBA_Environment * ev);
132
133 static CORBA_boolean
134 impl_setSelection (PortableServer_Servant _servant,
135                    const CORBA_long selectionNum,
136                    const CORBA_long startOffset,
137                    const CORBA_long endOffset,
138                    CORBA_Environment * ev);
139
140 static CORBA_boolean
141 impl_setCaretOffset (PortableServer_Servant _servant,
142                      const CORBA_long value,
143                      CORBA_Environment * ev); 
144
145 GType
146 accessibility_text_get_type (void)
147 {
148   static GType type = 0;
149
150   if (!type) {
151     static const GTypeInfo tinfo = {
152       sizeof (SpiTextClass),
153       (GBaseInitFunc) NULL,
154       (GBaseFinalizeFunc) NULL,
155       (GClassInitFunc) accessibility_text_class_init,
156       (GClassFinalizeFunc) NULL,
157       NULL, /* class data */
158       sizeof (SpiText),
159       0, /* n preallocs */
160       (GInstanceInitFunc) accessibility_text_init,
161       NULL /* value table */
162     };
163
164     /*
165      * Bonobo_type_unique auto-generates a load of
166      * CORBA structures for us. All derived types must
167      * use bonobo_type_unique.
168      */
169     type = bonobo_type_unique (
170                                PARENT_TYPE,
171                                POA_Accessibility_Text__init,
172                                NULL,
173                                G_STRUCT_OFFSET (SpiTextClass, epv),
174                                &tinfo,
175                                "SpiAccessibleText");
176   }
177
178   return type;
179 }
180
181 static void
182 accessibility_text_class_init (SpiTextClass *klass)
183 {
184   GObjectClass * object_class = (GObjectClass *) klass;
185   POA_Accessibility_Text__epv *epv = &klass->epv;
186   spi_text_parent_class = g_type_class_peek_parent (klass);
187
188   object_class->finalize = accessibility_text_object_finalize;
189
190   /* Initialize epv table */
191
192   epv->getText = impl_getText;
193   epv->getTextAfterOffset = impl_getTextAfterOffset;
194   epv->getCharacterAtOffset = impl_getCharacterAtOffset;
195   epv->getTextAtOffset = impl_getTextAtOffset;
196   epv->getTextBeforeOffset = impl_getTextBeforeOffset;
197   epv->_get_caretOffset = impl__get_caretOffset;
198   epv->getAttributes = impl_getAttributes;
199   epv->getCharacterExtents = impl_getCharacterExtents;
200   epv->_get_characterCount = impl__get_characterCount;
201   epv->getOffsetAtPoint = impl_getOffsetAtPoint;
202   epv->getNSelections = impl_getNSelections;
203   epv->getSelection = impl_getSelection;
204   epv->addSelection = impl_addSelection;
205   epv->removeSelection = impl_removeSelection;
206   epv->setSelection = impl_setSelection;
207   epv->setCaretOffset = impl_setCaretOffset;
208 }
209
210 static void
211 accessibility_text_init (SpiText *text)
212 {
213 }
214
215 static void
216 accessibility_text_object_finalize (GObject *obj)
217 {
218   SpiText *text = SPI_TEXT (obj);
219   g_object_unref (text->atko);
220   text->atko = NULL;
221   spi_text_parent_class->finalize (obj);
222 }
223
224 SpiText *
225 spi_text_interface_new (AtkObject *obj)
226 {
227   SpiText *new_text = 
228     SPI_TEXT (g_object_new (accessibility_text_get_type (), NULL));
229   new_text->atko = obj;
230   g_object_ref (obj);
231   return new_text;
232 }
233
234
235
236 static CORBA_string
237 impl_getText (PortableServer_Servant _servant,
238               const CORBA_long startOffset,
239               const CORBA_long endOffset,
240               CORBA_Environment * ev)
241 {
242   SpiText *text;
243   gchar *txt;
244   CORBA_string rv;
245   BonoboObject *obj;
246   
247   obj = (bonobo_object_from_servant (_servant));
248   g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
249   text = SPI_TEXT (obj);
250   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
251   
252   txt = atk_text_get_text (ATK_TEXT(text->atko),
253                        (gint) startOffset, (gint) endOffset);
254   if (txt)
255     {
256       rv = CORBA_string_dup (txt);
257       g_free (txt);
258     }
259   else
260     rv = CORBA_string_dup ("");
261   return rv;
262 }
263
264
265
266 CORBA_string
267 impl_getTextAfterOffset (PortableServer_Servant _servant,
268                          const CORBA_long offset,
269                          const
270                          Accessibility_TEXT_BOUNDARY_TYPE
271                          type, CORBA_long * startOffset,
272                          CORBA_long * endOffset,
273                          CORBA_Environment * ev)
274 {
275   SpiText *text;
276   gchar *txt;
277   CORBA_char *rv;
278   gint intStartOffset, intEndOffset;
279   BonoboObject *obj;
280
281   obj = (bonobo_object_from_servant (_servant));
282   g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
283   text = SPI_TEXT (obj);
284   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
285   
286   txt = atk_text_get_text_after_offset (ATK_TEXT(text->atko),
287                                     (gint) offset, (AtkTextBoundary) type,
288                                     &intStartOffset, &intEndOffset);
289   *startOffset = (CORBA_long) intStartOffset;
290   *endOffset = (CORBA_long) intEndOffset;
291
292   if (txt)
293     {
294       rv = CORBA_string_dup (txt);
295       g_free (txt);
296       }
297   else
298     rv = CORBA_string_dup ("");
299   return rv;
300 }
301
302
303
304 static CORBA_string
305 impl_getTextAtOffset (PortableServer_Servant _servant,
306                       const CORBA_long offset,
307                       const Accessibility_TEXT_BOUNDARY_TYPE type,
308                       CORBA_long * startOffset,
309                       CORBA_long * endOffset,
310                       CORBA_Environment * ev)
311 {
312   SpiText *text;
313   CORBA_char *txt;
314   CORBA_char *rv;
315   gint intStartOffset, intEndOffset;
316   BonoboObject *obj;
317
318   obj = (bonobo_object_from_servant (_servant));
319   g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
320   text = SPI_TEXT (obj);
321   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
322
323   txt = (CORBA_char *) atk_text_get_text_at_offset (ATK_TEXT (text->atko),
324                                     (gint) offset, (AtkTextBoundary) type,
325                                     &intStartOffset, &intEndOffset);
326   *startOffset = (CORBA_long) intStartOffset;
327   *endOffset = (CORBA_long) intEndOffset;
328
329   if (txt)
330     {
331       rv = CORBA_string_dup (txt);
332       g_free (txt);
333     }
334   else
335     rv = CORBA_string_dup ("");
336
337   return rv;
338 }
339
340
341 static CORBA_unsigned_long
342 impl_getCharacterAtOffset (PortableServer_Servant _servant,
343                            const CORBA_long offset,
344                            CORBA_Environment * ev)
345 {
346   SpiText *text;
347   BonoboObject *obj;
348   obj = (bonobo_object_from_servant (_servant));
349   
350   g_return_val_if_fail (IS_TEXT (obj), (CORBA_unsigned_long)0);
351   text = SPI_TEXT (obj);
352   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_unsigned_long)0);
353
354   return (CORBA_unsigned_long)
355     atk_text_get_character_at_offset (ATK_TEXT(text->atko), (gint) offset);
356 }
357
358
359 static CORBA_string
360 impl_getTextBeforeOffset (PortableServer_Servant _servant,
361                           const CORBA_long offset,
362                           const
363                           Accessibility_TEXT_BOUNDARY_TYPE
364                           type, CORBA_long * startOffset,
365                           CORBA_long * endOffset,
366                           CORBA_Environment * ev)
367 {
368   SpiText *text;
369   gchar *txt;
370   CORBA_char *rv;
371   gint intStartOffset, intEndOffset;
372   BonoboObject *obj;
373
374   obj = (bonobo_object_from_servant (_servant));
375   g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
376   text = SPI_TEXT (obj);
377   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
378
379   txt = atk_text_get_text_before_offset (ATK_TEXT(text->atko),
380                                     (gint) offset, (AtkTextBoundary) type,
381                                     &intStartOffset, &intEndOffset);
382   *startOffset = (CORBA_long) intStartOffset;
383   *endOffset = (CORBA_long) intEndOffset;
384
385   if (txt)
386     {
387       rv = CORBA_string_dup (txt);
388       g_free (txt);
389     }
390   else
391     rv = CORBA_string_dup ("");
392   return rv;
393 }
394
395
396 static CORBA_long
397 impl__get_caretOffset (PortableServer_Servant _servant,
398                      CORBA_Environment * ev)
399 {
400   SpiText *text;
401   BonoboObject *obj;
402
403   obj = (bonobo_object_from_servant (_servant));
404   g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)-1);
405   text = SPI_TEXT (obj);
406   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_long)-1);
407   
408   return (CORBA_long)
409     atk_text_get_caret_offset (ATK_TEXT(text->atko));
410 }
411
412
413
414 static CORBA_string
415 impl_getAttributes (PortableServer_Servant _servant,
416                        const CORBA_long offset,
417                        CORBA_long * startOffset,
418                        CORBA_long * endOffset,
419                        CORBA_Environment * ev)
420 {
421   SpiText *text;
422   BonoboObject *obj;
423
424   obj = (bonobo_object_from_servant (_servant));
425   g_return_val_if_fail (IS_TEXT (obj), (CORBA_char *)"");
426   text = SPI_TEXT (obj);
427   g_return_val_if_fail (ATK_IS_TEXT (text->atko), (CORBA_char *)"");
428
429   g_print ("getAttributes not yet implemented.\n");
430
431   return CORBA_string_dup ("");
432 }
433
434 static void 
435 impl_getCharacterExtents (PortableServer_Servant _servant,
436                           const CORBA_long offset, CORBA_long * x,
437                           CORBA_long * y, CORBA_long * width,
438                           CORBA_long * height,
439                           const CORBA_short coordType,
440                           CORBA_Environment * ev)
441 {
442   SpiText *text;
443   BonoboObject *obj;
444
445   obj = (bonobo_object_from_servant (_servant));
446   g_return_if_fail (IS_TEXT (obj));
447   text = SPI_TEXT (obj);
448   g_return_if_fail (ATK_IS_TEXT (text->atko));
449
450   atk_text_get_character_extents (ATK_TEXT(text->atko), (gint) offset,
451                                   (gint *) x, (gint *) y, (gint *) width, (gint *) height,
452                                   (AtkCoordType) coordType);
453 }
454
455
456
457 static CORBA_long
458 impl__get_characterCount (PortableServer_Servant _servant,
459                         CORBA_Environment * ev)
460 {
461   SpiText *text;
462   BonoboObject *obj;
463   CORBA_long retval;
464
465   obj = (bonobo_object_from_servant (_servant));
466   g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)0);
467   text = SPI_TEXT (obj);
468
469   retval = (CORBA_long)
470     atk_text_get_character_count (ATK_TEXT(text->atko));
471
472   return retval;
473 }
474
475
476
477 static CORBA_long
478 impl_getOffsetAtPoint (PortableServer_Servant _servant,
479                        const CORBA_long x, const CORBA_long y,
480                        const CORBA_short coordType,
481                        CORBA_Environment * ev)
482 {
483   SpiText *text;
484   BonoboObject *obj;
485
486   obj = (bonobo_object_from_servant (_servant));
487   g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)-1);
488   text = SPI_TEXT (obj);
489
490   return (CORBA_long)
491     atk_text_get_offset_at_point (ATK_TEXT(text->atko),
492                                   (gint) x, (gint) y, (AtkCoordType) coordType);
493 }
494
495
496
497 static CORBA_long
498 impl_getNSelections (PortableServer_Servant _servant,
499                      CORBA_Environment * ev)
500 {
501   SpiText *text;
502   BonoboObject *obj;
503
504   obj = (bonobo_object_from_servant (_servant));
505   g_return_val_if_fail (IS_TEXT (obj), (CORBA_long)0);
506   text = SPI_TEXT (obj);
507
508   return (CORBA_long)
509     atk_text_get_n_selections (ATK_TEXT(text->atko));
510 }
511
512
513
514 static void 
515 impl_getSelection (PortableServer_Servant _servant,
516                    const CORBA_long selectionNum,
517                    CORBA_long * startOffset, CORBA_long * endOffset,
518                    CORBA_Environment * ev)
519 {
520   SpiText *text;
521   BonoboObject *obj;
522
523   obj = (bonobo_object_from_servant (_servant));
524   g_return_if_fail (IS_TEXT (obj));
525   text = SPI_TEXT (obj);
526
527   atk_text_get_selection (ATK_TEXT(text->atko), (gint) selectionNum,
528                           (gint *) startOffset, (gint *) endOffset);
529 }
530
531
532
533 static CORBA_boolean
534 impl_addSelection (PortableServer_Servant _servant,
535                    const CORBA_long startOffset,
536                    const CORBA_long endOffset,
537                    CORBA_Environment * ev)
538 {
539   SpiText *text;
540   BonoboObject *obj;
541
542   obj = (bonobo_object_from_servant (_servant));
543   g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
544   text = SPI_TEXT (obj);
545
546   return (CORBA_boolean)
547     atk_text_add_selection (ATK_TEXT(text->atko),
548                             (gint) startOffset, (gint) endOffset);
549 }
550
551
552
553 static CORBA_boolean
554 impl_removeSelection (PortableServer_Servant _servant,
555                       const CORBA_long selectionNum,
556                       CORBA_Environment * ev)
557 {
558   SpiText *text;
559   BonoboObject *obj;
560
561   obj = (bonobo_object_from_servant (_servant));
562   g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
563   text = SPI_TEXT (obj);
564
565   return (CORBA_boolean)
566     atk_text_remove_selection (ATK_TEXT(text->atko), (gint) selectionNum);
567 }
568
569
570
571 static CORBA_boolean
572 impl_setSelection (PortableServer_Servant _servant,
573                    const CORBA_long selectionNum,
574                    const CORBA_long startOffset,
575                    const CORBA_long endOffset,
576                    CORBA_Environment * ev)
577 {
578   SpiText *text;
579   BonoboObject *obj;
580
581   obj = (bonobo_object_from_servant (_servant));
582   g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
583   text = SPI_TEXT (obj);
584
585   return (CORBA_boolean)
586     atk_text_set_selection (ATK_TEXT(text->atko),
587                             (gint) selectionNum, (gint) startOffset, (gint) endOffset);
588 }
589
590
591
592 static CORBA_boolean
593 impl_setCaretOffset (PortableServer_Servant _servant,
594                      const CORBA_long value,
595                      CORBA_Environment * ev)
596 {
597   SpiText *text;
598   BonoboObject *obj;
599
600   obj = (bonobo_object_from_servant (_servant));
601   g_return_val_if_fail (IS_TEXT (obj), (CORBA_boolean)FALSE);
602   text = SPI_TEXT (obj);
603
604   return (CORBA_boolean)
605     atk_text_set_caret_offset (ATK_TEXT(text->atko), (gint) value);
606 }
607
608
609
610 static void 
611 impl_getRowColAtOffset (PortableServer_Servant _servant,
612                         const CORBA_long offset, CORBA_long * row,
613                         CORBA_long * column, CORBA_Environment * ev)
614 {
615   SpiText *text;
616   BonoboObject *obj;
617
618   obj = (bonobo_object_from_servant (_servant));
619   g_return_if_fail (IS_TEXT (obj));
620   text = SPI_TEXT (obj);
621
622   g_print ("getRowColAtOffset not yet implemented\n");
623 }
624