Initial commit.
[platform/core/uifw/at-spi2-atk.git] / libspi / table.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2008 Novell, Inc.
6  * Copyright 2001, 2002 Sun Microsystems Inc.,
7  * Copyright 2001, 2002 Ximian, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include "accessible.h"
26
27 static AtkTable *
28 get_table (DBusMessage * message)
29 {
30   AtkObject *obj = spi_dbus_get_object (dbus_message_get_path (message));
31   if (!obj)
32     return NULL;
33   return ATK_TABLE (obj);
34 }
35
36 static AtkTable *
37 get_table_from_path (const char *path, void *user_data)
38 {
39   AtkObject *obj = spi_dbus_get_object (path);
40   if (!obj)
41     return NULL;
42   return ATK_TABLE (obj);
43 }
44
45 static dbus_bool_t
46 impl_get_nRows (const char *path, DBusMessageIter * iter, void *user_data)
47 {
48   AtkTable *table = get_table_from_path (path, user_data);
49   if (!table)
50     return FALSE;
51   return droute_return_v_int32 (iter, atk_table_get_n_rows (table));
52 }
53
54 static char *
55 impl_get_nRows_str (void *datum)
56 {
57   g_assert (ATK_IS_TABLE (datum));
58   return g_strdup_printf ("%d", atk_table_get_n_rows ((AtkTable *) datum));
59 }
60
61 static dbus_bool_t
62 impl_get_nColumns (const char *path, DBusMessageIter * iter, void *user_data)
63 {
64   AtkTable *table = get_table_from_path (path, user_data);
65   if (!table)
66     return FALSE;
67   return droute_return_v_int32 (iter, atk_table_get_n_columns (table));
68 }
69
70 static char *
71 impl_get_nColumns_str (void *datum)
72 {
73   g_assert (ATK_IS_TABLE (datum));
74   return g_strdup_printf ("%d", atk_table_get_n_columns ((AtkTable *) datum));
75 }
76
77 static dbus_bool_t
78 impl_get_caption (const char *path, DBusMessageIter * iter, void *user_data)
79 {
80   AtkTable *table = get_table_from_path (path, user_data);
81   if (!table)
82     return FALSE;
83   return spi_dbus_return_v_object (iter, atk_table_get_caption (table),
84                                    FALSE);
85 }
86
87 static char *
88 impl_get_caption_str (void *datum)
89 {
90   AtkTable *table = (AtkTable *) datum;
91   g_assert (ATK_IS_TABLE (datum));
92   return spi_dbus_get_path (atk_table_get_caption (table));
93 }
94
95 static dbus_bool_t
96 impl_get_summary (const char *path, DBusMessageIter * iter, void *user_data)
97 {
98   AtkTable *table = get_table_from_path (path, user_data);
99   if (!table)
100     return FALSE;
101   return spi_dbus_return_v_object (iter, atk_table_get_summary (table),
102                                    FALSE);
103 }
104
105 static char *
106 impl_get_summary_str (void *datum)
107 {
108   AtkTable *table = (AtkTable *) datum;
109   g_assert (ATK_IS_TABLE (datum));
110   return spi_dbus_get_path (atk_table_get_summary (table));
111 }
112
113 static dbus_bool_t
114 impl_get_nSelectedRows (const char *path, DBusMessageIter * iter,
115                         void *user_data)
116 {
117   AtkTable *table = get_table_from_path (path, user_data);
118   gint *selected_rows = NULL;
119   int count;
120   if (!table)
121     return FALSE;
122   count = atk_table_get_selected_rows (table, &selected_rows);
123   if (selected_rows)
124     g_free (selected_rows);
125   return droute_return_v_int32 (iter, count);
126 }
127
128 static char *
129 impl_get_nSelectedRows_str (void *datum)
130 {
131   gint count;
132   gint *selected_rows = NULL;
133   g_assert (ATK_IS_TABLE (datum));
134   count = atk_table_get_selected_rows ((AtkTable *) datum, &selected_rows);
135   if (selected_rows)
136     g_free (selected_rows);
137   return g_strdup_printf ("%d", count);
138 }
139
140 static dbus_bool_t
141 impl_get_nSelectedColumns (const char *path, DBusMessageIter * iter,
142                            void *user_data)
143 {
144   AtkTable *table = get_table_from_path (path, user_data);
145   gint *selected_columns = NULL;
146   int count;
147   if (!table)
148     return FALSE;
149   count = atk_table_get_selected_columns (table, &selected_columns);
150   if (selected_columns)
151     g_free (selected_columns);
152   return droute_return_v_int32 (iter, count);
153 }
154
155 static char *
156 impl_get_nSelectedColumns_str (void *datum)
157 {
158   gint count;
159   gint *selected_columns = NULL;
160   g_assert (ATK_IS_TABLE (datum));
161   count =
162     atk_table_get_selected_columns ((AtkTable *) datum, &selected_columns);
163   if (selected_columns)
164     g_free (selected_columns);
165   return g_strdup_printf ("%d", count);
166 }
167
168
169 static DBusMessage *
170 impl_getAccessibleAt (DBusConnection * bus, DBusMessage * message,
171                       void *user_data)
172 {
173   AtkTable *table = get_table (message);
174   dbus_int32_t row, column;
175   DBusError error;
176   AtkObject *obj;
177
178   if (!table)
179     return spi_dbus_general_error (message);
180   dbus_error_init (&error);
181   if (!dbus_message_get_args
182       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
183        DBUS_TYPE_INVALID))
184     {
185       return SPI_DBUS_RETURN_ERROR (message, &error);
186     }
187   obj = atk_table_ref_at (table, row, column);
188   return spi_dbus_return_object (message, obj, TRUE);
189 }
190
191 static DBusMessage *
192 impl_getIndexAt (DBusConnection * bus, DBusMessage * message, void *user_data)
193 {
194   AtkTable *table = get_table (message);
195   dbus_int32_t row, column;
196   dbus_int32_t index;
197   DBusError error;
198   DBusMessage *reply;
199
200   if (!table)
201     return spi_dbus_general_error (message);
202   dbus_error_init (&error);
203   if (!dbus_message_get_args
204       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
205        DBUS_TYPE_INVALID))
206     {
207       return SPI_DBUS_RETURN_ERROR (message, &error);
208     }
209   index = atk_table_get_index_at (table, row, column);
210   reply = dbus_message_new_method_return (message);
211   if (reply)
212     {
213       dbus_message_append_args (reply, DBUS_TYPE_INT32, &index,
214                                 DBUS_TYPE_INVALID);
215     }
216   return reply;
217 }
218
219 static DBusMessage *
220 impl_getRowAtIndex (DBusConnection * bus, DBusMessage * message,
221                     void *user_data)
222 {
223   AtkTable *table = get_table (message);
224   dbus_int32_t index;
225   dbus_int32_t row;
226   DBusError error;
227   DBusMessage *reply;
228
229   if (!table)
230     return spi_dbus_general_error (message);
231   dbus_error_init (&error);
232   if (!dbus_message_get_args
233       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
234     {
235       return SPI_DBUS_RETURN_ERROR (message, &error);
236     }
237   row = atk_table_get_row_at_index (table, index);
238   reply = dbus_message_new_method_return (message);
239   if (reply)
240     {
241       dbus_message_append_args (reply, DBUS_TYPE_INT32, &row,
242                                 DBUS_TYPE_INVALID);
243     }
244   return reply;
245 }
246
247 static DBusMessage *
248 impl_getColumnAtIndex (DBusConnection * bus, DBusMessage * message,
249                        void *user_data)
250 {
251   AtkTable *table = get_table (message);
252   dbus_int32_t index;
253   dbus_int32_t column;
254   DBusError error;
255   DBusMessage *reply;
256
257   if (!table)
258     return spi_dbus_general_error (message);
259   dbus_error_init (&error);
260   if (!dbus_message_get_args
261       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
262     {
263       return SPI_DBUS_RETURN_ERROR (message, &error);
264     }
265   column = atk_table_get_column_at_index (table, index);
266   reply = dbus_message_new_method_return (message);
267   if (reply)
268     {
269       dbus_message_append_args (reply, DBUS_TYPE_INT32, &column,
270                                 DBUS_TYPE_INVALID);
271     }
272   return reply;
273 }
274
275 static DBusMessage *
276 impl_getRowDescription (DBusConnection * bus, DBusMessage * message,
277                         void *user_data)
278 {
279   AtkTable *table = get_table (message);
280   dbus_int32_t row;
281   const gchar *description;
282   DBusError error;
283   DBusMessage *reply;
284
285   if (!table)
286     return spi_dbus_general_error (message);
287   dbus_error_init (&error);
288   if (!dbus_message_get_args
289       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
290     {
291       return SPI_DBUS_RETURN_ERROR (message, &error);
292     }
293   description = atk_table_get_row_description (table, row);
294   if (!description)
295     description = "";
296   reply = dbus_message_new_method_return (message);
297   if (reply)
298     {
299       dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
300                                 DBUS_TYPE_INVALID);
301     }
302   return reply;
303 }
304
305 static DBusMessage *
306 impl_getColumnDescription (DBusConnection * bus, DBusMessage * message,
307                            void *user_data)
308 {
309   AtkTable *table = get_table (message);
310   dbus_int32_t column;
311   const char *description;
312   DBusError error;
313   DBusMessage *reply;
314
315   if (!table)
316     return spi_dbus_general_error (message);
317   dbus_error_init (&error);
318   if (!dbus_message_get_args
319       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
320     {
321       return SPI_DBUS_RETURN_ERROR (message, &error);
322     }
323   description = atk_table_get_column_description (table, column);
324   if (!description)
325     description = "";
326   reply = dbus_message_new_method_return (message);
327   if (reply)
328     {
329       dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
330                                 DBUS_TYPE_INVALID);
331     }
332   return reply;
333 }
334
335 static DBusMessage *
336 impl_getRowExtentAt (DBusConnection * bus, DBusMessage * message,
337                      void *user_data)
338 {
339   AtkTable *table = get_table (message);
340   dbus_int32_t row, column;
341   dbus_int32_t extent;
342   DBusError error;
343   DBusMessage *reply;
344
345   if (!table)
346     return spi_dbus_general_error (message);
347   dbus_error_init (&error);
348   if (!dbus_message_get_args
349       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
350        DBUS_TYPE_INVALID))
351     {
352       return SPI_DBUS_RETURN_ERROR (message, &error);
353     }
354   extent = atk_table_get_row_extent_at (table, row, column);
355   reply = dbus_message_new_method_return (message);
356   if (reply)
357     {
358       dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
359                                 DBUS_TYPE_INVALID);
360     }
361   return reply;
362 }
363
364 static DBusMessage *
365 impl_getColumnExtentAt (DBusConnection * bus, DBusMessage * message,
366                         void *user_data)
367 {
368   AtkTable *table = get_table (message);
369   dbus_int32_t row, column;
370   dbus_int32_t extent;
371   DBusError error;
372   DBusMessage *reply;
373
374   if (!table)
375     return spi_dbus_general_error (message);
376   dbus_error_init (&error);
377   if (!dbus_message_get_args
378       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
379        DBUS_TYPE_INVALID))
380     {
381       return SPI_DBUS_RETURN_ERROR (message, &error);
382     }
383   extent = atk_table_get_column_extent_at (table, row, column);
384   reply = dbus_message_new_method_return (message);
385   if (reply)
386     {
387       dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
388                                 DBUS_TYPE_INVALID);
389     }
390   return reply;
391 }
392
393 static DBusMessage *
394 impl_getRowHeader (DBusConnection * bus, DBusMessage * message,
395                    void *user_data)
396 {
397   AtkTable *table = get_table (message);
398   dbus_int32_t row;
399   DBusError error;
400   AtkObject *obj;
401
402   if (!table)
403     return spi_dbus_general_error (message);
404   dbus_error_init (&error);
405   if (!dbus_message_get_args
406       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
407     {
408       return SPI_DBUS_RETURN_ERROR (message, &error);
409     }
410   obj = atk_table_get_row_header (table, row);
411   return spi_dbus_return_object (message, obj, FALSE);
412 }
413
414 static DBusMessage *
415 impl_getColumnHeader (DBusConnection * bus, DBusMessage * message,
416                       void *user_data)
417 {
418   AtkTable *table = get_table (message);
419   dbus_int32_t column;
420   DBusError error;
421   AtkObject *obj;
422
423   if (!table)
424     return spi_dbus_general_error (message);
425   dbus_error_init (&error);
426   if (!dbus_message_get_args
427       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
428     {
429       return SPI_DBUS_RETURN_ERROR (message, &error);
430     }
431   obj = atk_table_get_column_header (table, column);
432   return spi_dbus_return_object (message, obj, FALSE);
433 }
434
435 static DBusMessage *
436 impl_getSelectedRows (DBusConnection * bus, DBusMessage * message,
437                       void *user_data)
438 {
439   AtkTable *table = get_table (message);
440   gint *selected_rows = NULL;
441   gint count;
442   DBusMessage *reply;
443
444   if (!table)
445     return spi_dbus_general_error (message);
446   count = atk_table_get_selected_rows (table, &selected_rows);
447   if (!selected_rows)
448     count = 0;
449   reply = dbus_message_new_method_return (message);
450   if (reply)
451     {
452       /* tbd - figure out if this is safe for a 0-length array */
453       dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
454                                 &selected_rows, count, DBUS_TYPE_INVALID);
455     }
456   if (selected_rows)
457     g_free (selected_rows);
458   return reply;
459 }
460
461 static DBusMessage *
462 impl_getSelectedColumns (DBusConnection * bus, DBusMessage * message,
463                          void *user_data)
464 {
465   AtkTable *table = get_table (message);
466   gint *selected_columns = NULL;
467   gint count;
468   DBusMessage *reply;
469
470   if (!table)
471     return spi_dbus_general_error (message);
472   count = atk_table_get_selected_columns (table, &selected_columns);
473   if (!selected_columns)
474     count = 0;
475   reply = dbus_message_new_method_return (message);
476   if (reply)
477     {
478       /* tbd - figure out if this is safe for a 0-length array */
479       dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
480                                 &selected_columns, count, DBUS_TYPE_INVALID);
481     }
482   if (selected_columns)
483     g_free (selected_columns);
484   return reply;
485 }
486
487 static DBusMessage *
488 impl_isRowSelected (DBusConnection * bus, DBusMessage * message,
489                     void *user_data)
490 {
491   AtkTable *table = get_table (message);
492   dbus_int32_t row;
493   DBusError error;
494   DBusMessage *reply;
495   dbus_bool_t ret;
496
497   if (!table)
498     return spi_dbus_general_error (message);
499   dbus_error_init (&error);
500   if (!dbus_message_get_args
501       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
502     {
503       return SPI_DBUS_RETURN_ERROR (message, &error);
504     }
505   ret = atk_table_is_row_selected (table, row);
506   reply = dbus_message_new_method_return (message);
507   if (reply)
508     {
509       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
510                                 DBUS_TYPE_INVALID);
511     }
512   return reply;
513 }
514
515 static DBusMessage *
516 impl_isColumnSelected (DBusConnection * bus, DBusMessage * message,
517                        void *user_data)
518 {
519   AtkTable *table = get_table (message);
520   dbus_int32_t column;
521   DBusError error;
522   DBusMessage *reply;
523   dbus_bool_t ret;
524
525   if (!table)
526     return spi_dbus_general_error (message);
527   dbus_error_init (&error);
528   if (!dbus_message_get_args
529       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
530     {
531       return SPI_DBUS_RETURN_ERROR (message, &error);
532     }
533   ret = atk_table_is_column_selected (table, column);
534   reply = dbus_message_new_method_return (message);
535   if (reply)
536     {
537       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
538                                 DBUS_TYPE_INVALID);
539     }
540   return reply;
541 }
542
543 static DBusMessage *
544 impl_isSelected (DBusConnection * bus, DBusMessage * message, void *user_data)
545 {
546   AtkTable *table = get_table (message);
547   dbus_int32_t row, column;
548   DBusError error;
549   DBusMessage *reply;
550   dbus_bool_t ret;
551
552   if (!table)
553     return spi_dbus_general_error (message);
554   dbus_error_init (&error);
555   if (!dbus_message_get_args
556       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
557        DBUS_TYPE_INVALID))
558     {
559       return SPI_DBUS_RETURN_ERROR (message, &error);
560     }
561   ret = atk_table_is_selected (table, row, column);
562   reply = dbus_message_new_method_return (message);
563   if (reply)
564     {
565       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
566                                 DBUS_TYPE_INVALID);
567     }
568   return reply;
569 }
570
571 static DBusMessage *
572 impl_addRowSelection (DBusConnection * bus, DBusMessage * message,
573                       void *user_data)
574 {
575   AtkTable *table = get_table (message);
576   dbus_int32_t row;
577   DBusError error;
578   DBusMessage *reply;
579   dbus_bool_t ret;
580
581   if (!table)
582     return spi_dbus_general_error (message);
583   dbus_error_init (&error);
584   if (!dbus_message_get_args
585       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
586     {
587       return SPI_DBUS_RETURN_ERROR (message, &error);
588     }
589   ret = atk_table_add_row_selection (table, row);
590   reply = dbus_message_new_method_return (message);
591   if (reply)
592     {
593       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
594                                 DBUS_TYPE_INVALID);
595     }
596   return reply;
597 }
598
599 static DBusMessage *
600 impl_addColumnSelection (DBusConnection * bus, DBusMessage * message,
601                          void *user_data)
602 {
603   AtkTable *table = get_table (message);
604   dbus_int32_t column;
605   DBusError error;
606   DBusMessage *reply;
607   dbus_bool_t ret;
608
609   if (!table)
610     return spi_dbus_general_error (message);
611   dbus_error_init (&error);
612   if (!dbus_message_get_args
613       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
614     {
615       return SPI_DBUS_RETURN_ERROR (message, &error);
616     }
617   ret = atk_table_add_column_selection (table, column);
618   reply = dbus_message_new_method_return (message);
619   if (reply)
620     {
621       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
622                                 DBUS_TYPE_INVALID);
623     }
624   return reply;
625 }
626
627 static DBusMessage *
628 impl_removeRowSelection (DBusConnection * bus, DBusMessage * message,
629                          void *user_data)
630 {
631   AtkTable *table = get_table (message);
632   dbus_int32_t row;
633   DBusError error;
634   DBusMessage *reply;
635   dbus_bool_t ret;
636
637   if (!table)
638     return spi_dbus_general_error (message);
639   dbus_error_init (&error);
640   if (!dbus_message_get_args
641       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
642     {
643       return SPI_DBUS_RETURN_ERROR (message, &error);
644     }
645   ret = atk_table_remove_row_selection (table, row);
646   reply = dbus_message_new_method_return (message);
647   if (reply)
648     {
649       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
650                                 DBUS_TYPE_INVALID);
651     }
652   return reply;
653 }
654
655 static DBusMessage *
656 impl_removeColumnSelection (DBusConnection * bus, DBusMessage * message,
657                             void *user_data)
658 {
659   AtkTable *table = get_table (message);
660   dbus_int32_t column;
661   DBusError error;
662   DBusMessage *reply;
663   dbus_bool_t ret;
664
665   if (!table)
666     return spi_dbus_general_error (message);
667   dbus_error_init (&error);
668   if (!dbus_message_get_args
669       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
670     {
671       return SPI_DBUS_RETURN_ERROR (message, &error);
672     }
673   ret = atk_table_remove_column_selection (table, column);
674   reply = dbus_message_new_method_return (message);
675   if (reply)
676     {
677       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
678                                 DBUS_TYPE_INVALID);
679     }
680   return reply;
681 }
682
683 static DBusMessage *
684 impl_getRowColumnExtentsAtIndex (DBusConnection * bus, DBusMessage * message,
685                                  void *user_data)
686 {
687   AtkTable *table = get_table (message);
688   dbus_int32_t index;
689   DBusError error;
690   dbus_int32_t row, column, row_extents, col_extents;
691   dbus_bool_t is_selected;
692   dbus_bool_t ret;
693   DBusMessage *reply;
694
695   AtkObject *cell;
696   AtkRole role;
697
698   if (!table)
699     return spi_dbus_general_error (message);
700   dbus_error_init (&error);
701   if (!dbus_message_get_args
702       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
703     {
704       return SPI_DBUS_RETURN_ERROR (message, &error);
705     }
706   column = atk_table_get_column_at_index (table, index);
707   row = atk_table_get_row_at_index (table, index);
708   row_extents = atk_table_get_row_extent_at (table, row, column);
709   col_extents = atk_table_get_column_extent_at (table, row, column);
710   is_selected = atk_table_is_selected (table, row, column);
711   cell = atk_table_ref_at (table, row, column);
712   role = atk_object_get_role (cell);
713   g_object_unref (cell);
714   ret = (role == ATK_ROLE_TABLE_CELL ? TRUE : FALSE);
715   reply = dbus_message_new_method_return (message);
716   if (reply)
717     {
718       dbus_message_append_args (reply, DBUS_TYPE_INT32, row, DBUS_TYPE_INT32,
719                                 column, DBUS_TYPE_INT32, row_extents,
720                                 DBUS_TYPE_INT32, col_extents,
721                                 DBUS_TYPE_BOOLEAN, is_selected,
722                                 DBUS_TYPE_BOOLEAN, &ret, DBUS_TYPE_INVALID);
723     }
724   return reply;
725 }
726
727 static DRouteMethod methods[] = {
728   {DROUTE_METHOD, impl_getAccessibleAt, "getAccessibleAt",
729    "i,row,i:i,column,i:o,,o"},
730   {DROUTE_METHOD, impl_getIndexAt, "getIndexAt", "i,row,i:i,column,i:i,,o"},
731   {DROUTE_METHOD, impl_getRowAtIndex, "getRowAtIndex", "i,index,i:i,,o"},
732   {DROUTE_METHOD, impl_getColumnAtIndex, "getColumnAtIndex",
733    "i,index,i:i,,o"},
734   {DROUTE_METHOD, impl_getRowDescription, "getRowDescription",
735    "i,row,i:s,,o"},
736   {DROUTE_METHOD, impl_getColumnDescription, "getColumnDescription",
737    "i,column,i:s,,o"},
738   {DROUTE_METHOD, impl_getRowExtentAt, "getRowExtentAt",
739    "i,row,i:i,column,i:i,,o"},
740   {DROUTE_METHOD, impl_getColumnExtentAt, "getColumnExtentAt",
741    "i,row,i:i,column,i:i,,o"},
742   {DROUTE_METHOD, impl_getRowHeader, "getRowHeader", "i,row,i:o,,o"},
743   {DROUTE_METHOD, impl_getColumnHeader, "getColumnHeader", "i,column,i:o,,o"},
744   {DROUTE_METHOD, impl_getSelectedRows, "getSelectedRows", "ai,,o"},
745   {DROUTE_METHOD, impl_getSelectedColumns, "getSelectedColumns", "ai,,o"},
746   {DROUTE_METHOD, impl_isRowSelected, "isRowSelected", "i,row,i:b,,o"},
747   {DROUTE_METHOD, impl_isColumnSelected, "isColumnSelected",
748    "i,column,i:b,,o"},
749   {DROUTE_METHOD, impl_isSelected, "isSelected", "i,row,i:i,column,i:b,,o"},
750   {DROUTE_METHOD, impl_addRowSelection, "addRowSelection", "i,row,i:b,,o"},
751   {DROUTE_METHOD, impl_addColumnSelection, "addColumnSelection",
752    "i,column,i:b,,o"},
753   {DROUTE_METHOD, impl_removeRowSelection, "removeRowSelection",
754    "i,row,i:b,,o"},
755   {DROUTE_METHOD, impl_removeColumnSelection, "removeColumnSelection",
756    "i,column,i:b,,o"},
757   {DROUTE_METHOD, impl_getRowColumnExtentsAtIndex,
758    "getRowColumnExtentsAtIndex",
759    "i,index,i:i,row,o:i,col,o:i,row_extents,o:i,col_extents,o:b,is_selected,o:b,,o"},
760   {0, NULL, NULL, NULL}
761 };
762
763 static DRouteProperty properties[] = {
764   {impl_get_nRows, impl_get_nRows_str, NULL, NULL, "nRows", "i"},
765   {impl_get_nColumns, impl_get_nColumns_str, NULL, NULL, "nColumns", "i"},
766   {impl_get_caption, impl_get_caption_str, NULL, NULL, "caption", "o"},
767   {impl_get_summary, impl_get_summary_str, NULL, NULL, "summary", "o"},
768   {impl_get_nSelectedRows, impl_get_nSelectedRows_str, NULL, NULL,
769    "nSelectedRows", "i"},
770   {impl_get_nSelectedColumns, impl_get_nSelectedColumns_str, NULL, NULL,
771    "nSelectedColumns", "i"},
772   {NULL, NULL, NULL, NULL, NULL, NULL}
773 };
774
775 void
776 spi_initialize_table (DRouteData * data)
777 {
778   droute_add_interface (data, "org.freedesktop.accessibility.Table", methods,
779                         properties,
780                         (DRouteGetDatumFunction) get_table_from_path, NULL);
781 };