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