Change the name of interfaces from org.freedesktop.atspi to
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / adaptors / table-adaptor.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 <atk/atk.h>
26 #include <droute/droute.h>
27
28 #include "common/spi-dbus.h"
29 #include "object.h"
30 #include "introspection.h"
31
32 static dbus_bool_t
33 impl_get_NRows (DBusMessageIter * iter, void *user_data)
34 {
35   AtkTable *table = (AtkTable *) user_data;
36   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
37   return droute_return_v_int32 (iter, atk_table_get_n_rows (table));
38 }
39
40 static dbus_bool_t
41 impl_get_NColumns (DBusMessageIter * iter, void *user_data)
42 {
43   AtkTable *table = (AtkTable *) user_data;
44   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
45   return droute_return_v_int32 (iter, atk_table_get_n_columns (table));
46 }
47
48 static dbus_bool_t
49 impl_get_Caption (DBusMessageIter * iter, void *user_data)
50 {
51   AtkTable *table = (AtkTable *) user_data;
52   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
53   spi_object_append_v_reference (iter, atk_table_get_caption (table));
54   return TRUE;
55 }
56
57 static dbus_bool_t
58 impl_get_Summary (DBusMessageIter * iter, void *user_data)
59 {
60   AtkTable *table = (AtkTable *) user_data;
61   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
62   spi_object_append_v_reference (iter, atk_table_get_summary (table));
63   return TRUE;
64 }
65
66 static dbus_bool_t
67 impl_get_NSelectedRows (DBusMessageIter * iter, void *user_data)
68 {
69   AtkTable *table = (AtkTable *) user_data;
70   gint *selected_rows = NULL;
71   int count;
72   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
73   count = atk_table_get_selected_rows (table, &selected_rows);
74   if (selected_rows)
75     g_free (selected_rows);
76   return droute_return_v_int32 (iter, count);
77 }
78
79 static dbus_bool_t
80 impl_get_NSelectedColumns (DBusMessageIter * iter, void *user_data)
81 {
82   AtkTable *table = (AtkTable *) user_data;
83   gint *selected_columns = NULL;
84   int count;
85   g_return_val_if_fail (ATK_IS_TABLE (user_data), FALSE);
86   count = atk_table_get_selected_columns (table, &selected_columns);
87   if (selected_columns)
88     g_free (selected_columns);
89   return droute_return_v_int32 (iter, count);
90 }
91
92 static DBusMessage *
93 impl_GetAccessibleAt (DBusConnection * bus, DBusMessage * message,
94                       void *user_data)
95 {
96   AtkTable *table = (AtkTable *) user_data;
97   dbus_int32_t row, column;
98   DBusError error;
99   AtkObject *obj;
100
101   g_return_val_if_fail (ATK_IS_TABLE (user_data),
102                         droute_not_yet_handled_error (message));
103   dbus_error_init (&error);
104   if (!dbus_message_get_args
105       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
106        DBUS_TYPE_INVALID))
107     {
108       return droute_invalid_arguments_error (message);
109     }
110   obj = atk_table_ref_at (table, row, column);
111   return spi_object_return_reference (message, obj);
112 }
113
114 static DBusMessage *
115 impl_GetIndexAt (DBusConnection * bus, DBusMessage * message, void *user_data)
116 {
117   AtkTable *table = (AtkTable *) user_data;
118   dbus_int32_t row, column;
119   dbus_int32_t index;
120   DBusError error;
121   DBusMessage *reply;
122
123   g_return_val_if_fail (ATK_IS_TABLE (user_data),
124                         droute_not_yet_handled_error (message));
125   dbus_error_init (&error);
126   if (!dbus_message_get_args
127       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
128        DBUS_TYPE_INVALID))
129     {
130       return droute_invalid_arguments_error (message);
131     }
132   index = atk_table_get_index_at (table, row, column);
133   reply = dbus_message_new_method_return (message);
134   if (reply)
135     {
136       dbus_message_append_args (reply, DBUS_TYPE_INT32, &index,
137                                 DBUS_TYPE_INVALID);
138     }
139   return reply;
140 }
141
142 static DBusMessage *
143 impl_GetRowAtIndex (DBusConnection * bus, DBusMessage * message,
144                     void *user_data)
145 {
146   AtkTable *table = (AtkTable *) user_data;
147   dbus_int32_t index;
148   dbus_int32_t row;
149   DBusError error;
150   DBusMessage *reply;
151
152   g_return_val_if_fail (ATK_IS_TABLE (user_data),
153                         droute_not_yet_handled_error (message));
154   dbus_error_init (&error);
155   if (!dbus_message_get_args
156       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
157     {
158       return droute_invalid_arguments_error (message);
159     }
160   row = atk_table_get_row_at_index (table, index);
161   reply = dbus_message_new_method_return (message);
162   if (reply)
163     {
164       dbus_message_append_args (reply, DBUS_TYPE_INT32, &row,
165                                 DBUS_TYPE_INVALID);
166     }
167   return reply;
168 }
169
170 static DBusMessage *
171 impl_GetColumnAtIndex (DBusConnection * bus, DBusMessage * message,
172                        void *user_data)
173 {
174   AtkTable *table = (AtkTable *) user_data;
175   dbus_int32_t index;
176   dbus_int32_t column;
177   DBusError error;
178   DBusMessage *reply;
179
180   g_return_val_if_fail (ATK_IS_TABLE (user_data),
181                         droute_not_yet_handled_error (message));
182   dbus_error_init (&error);
183   if (!dbus_message_get_args
184       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
185     {
186       return droute_invalid_arguments_error (message);
187     }
188   column = atk_table_get_column_at_index (table, index);
189   reply = dbus_message_new_method_return (message);
190   if (reply)
191     {
192       dbus_message_append_args (reply, DBUS_TYPE_INT32, &column,
193                                 DBUS_TYPE_INVALID);
194     }
195   return reply;
196 }
197
198 static DBusMessage *
199 impl_GetRowDescription (DBusConnection * bus, DBusMessage * message,
200                         void *user_data)
201 {
202   dbus_int32_t row;
203   AtkTable *table = (AtkTable *) user_data;
204   const gchar *description;
205   DBusError error;
206   DBusMessage *reply;
207
208   g_return_val_if_fail (ATK_IS_TABLE (user_data),
209                         droute_not_yet_handled_error (message));
210   dbus_error_init (&error);
211   if (!dbus_message_get_args
212       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
213     {
214       return droute_invalid_arguments_error (message);
215     }
216   description = atk_table_get_row_description (table, row);
217   if (!description)
218     description = "";
219   reply = dbus_message_new_method_return (message);
220   if (reply)
221     {
222       dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
223                                 DBUS_TYPE_INVALID);
224     }
225   return reply;
226 }
227
228 static DBusMessage *
229 impl_GetColumnDescription (DBusConnection * bus, DBusMessage * message,
230                            void *user_data)
231 {
232   AtkTable *table = (AtkTable *) user_data;
233   dbus_int32_t column;
234   const char *description;
235   DBusError error;
236   DBusMessage *reply;
237
238   g_return_val_if_fail (ATK_IS_TABLE (user_data),
239                         droute_not_yet_handled_error (message));
240   dbus_error_init (&error);
241   if (!dbus_message_get_args
242       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
243     {
244       return droute_invalid_arguments_error (message);
245     }
246   description = atk_table_get_column_description (table, column);
247   if (!description)
248     description = "";
249   reply = dbus_message_new_method_return (message);
250   if (reply)
251     {
252       dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
253                                 DBUS_TYPE_INVALID);
254     }
255   return reply;
256 }
257
258 static DBusMessage *
259 impl_GetRowExtentAt (DBusConnection * bus, DBusMessage * message,
260                      void *user_data)
261 {
262   AtkTable *table = (AtkTable *) user_data;
263   dbus_int32_t row, column;
264   dbus_int32_t extent;
265   DBusError error;
266   DBusMessage *reply;
267
268   g_return_val_if_fail (ATK_IS_TABLE (user_data),
269                         droute_not_yet_handled_error (message));
270   dbus_error_init (&error);
271   if (!dbus_message_get_args
272       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
273        DBUS_TYPE_INVALID))
274     {
275       return droute_invalid_arguments_error (message);
276     }
277   extent = atk_table_get_row_extent_at (table, row, column);
278   reply = dbus_message_new_method_return (message);
279   if (reply)
280     {
281       dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
282                                 DBUS_TYPE_INVALID);
283     }
284   return reply;
285 }
286
287 static DBusMessage *
288 impl_GetColumnExtentAt (DBusConnection * bus, DBusMessage * message,
289                         void *user_data)
290 {
291   AtkTable *table = (AtkTable *) user_data;
292   dbus_int32_t row, column;
293   dbus_int32_t extent;
294   DBusError error;
295   DBusMessage *reply;
296
297   g_return_val_if_fail (ATK_IS_TABLE (user_data),
298                         droute_not_yet_handled_error (message));
299   dbus_error_init (&error);
300   if (!dbus_message_get_args
301       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
302        DBUS_TYPE_INVALID))
303     {
304       return droute_invalid_arguments_error (message);
305     }
306   extent = atk_table_get_column_extent_at (table, row, column);
307   reply = dbus_message_new_method_return (message);
308   if (reply)
309     {
310       dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
311                                 DBUS_TYPE_INVALID);
312     }
313   return reply;
314 }
315
316 static DBusMessage *
317 impl_GetRowHeader (DBusConnection * bus, DBusMessage * message,
318                    void *user_data)
319 {
320   AtkTable *table = (AtkTable *) user_data;
321   dbus_int32_t row;
322   DBusError error;
323   AtkObject *obj = NULL;
324
325   g_return_val_if_fail (ATK_IS_TABLE (user_data),
326                         droute_not_yet_handled_error (message));
327   dbus_error_init (&error);
328   if (!dbus_message_get_args
329       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
330     {
331       return droute_invalid_arguments_error (message);
332     }
333   obj = atk_table_get_row_header (table, row);
334   return spi_object_return_reference (message, obj);
335 }
336
337 static DBusMessage *
338 impl_GetColumnHeader (DBusConnection * bus, DBusMessage * message,
339                       void *user_data)
340 {
341   AtkTable *table = (AtkTable *) user_data;
342   dbus_int32_t column;
343   DBusError error;
344   AtkObject *obj;
345
346   g_return_val_if_fail (ATK_IS_TABLE (user_data),
347                         droute_not_yet_handled_error (message));
348   dbus_error_init (&error);
349   if (!dbus_message_get_args
350       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
351     {
352       return droute_invalid_arguments_error (message);
353     }
354   obj = atk_table_get_column_header (table, column);
355   obj = atk_table_get_column_header (table, column);
356   return spi_object_return_reference (message, obj);
357 }
358
359 static DBusMessage *
360 impl_GetSelectedRows (DBusConnection * bus, DBusMessage * message,
361                       void *user_data)
362 {
363   AtkTable *table = (AtkTable *) user_data;
364   gint *selected_rows = NULL;
365   gint count;
366   DBusMessage *reply;
367
368   g_return_val_if_fail (ATK_IS_TABLE (user_data),
369                         droute_not_yet_handled_error (message));
370   count = atk_table_get_selected_rows (table, &selected_rows);
371   if (!selected_rows)
372     count = 0;
373   reply = dbus_message_new_method_return (message);
374   if (reply)
375     {
376       /* tbd - figure out if this is safe for a 0-length array */
377       dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
378                                 &selected_rows, count, DBUS_TYPE_INVALID);
379     }
380   if (selected_rows)
381     g_free (selected_rows);
382   return reply;
383 }
384
385 static DBusMessage *
386 impl_GetSelectedColumns (DBusConnection * bus, DBusMessage * message,
387                          void *user_data)
388 {
389   AtkTable *table = (AtkTable *) user_data;
390   gint *selected_columns = NULL;
391   gint count;
392   DBusMessage *reply;
393
394   g_return_val_if_fail (ATK_IS_TABLE (user_data),
395                         droute_not_yet_handled_error (message));
396   count = atk_table_get_selected_columns (table, &selected_columns);
397   if (!selected_columns)
398     count = 0;
399   reply = dbus_message_new_method_return (message);
400   if (reply)
401     {
402       /* tbd - figure out if this is safe for a 0-length array */
403       dbus_message_append_args (reply, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
404                                 &selected_columns, count, DBUS_TYPE_INVALID);
405     }
406   if (selected_columns)
407     g_free (selected_columns);
408   return reply;
409 }
410
411 static DBusMessage *
412 impl_IsRowSelected (DBusConnection * bus, DBusMessage * message,
413                     void *user_data)
414 {
415   AtkTable *table = (AtkTable *) user_data;
416   dbus_int32_t row;
417   DBusError error;
418   DBusMessage *reply;
419   dbus_bool_t ret;
420
421   g_return_val_if_fail (ATK_IS_TABLE (user_data),
422                         droute_not_yet_handled_error (message));
423   dbus_error_init (&error);
424   if (!dbus_message_get_args
425       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
426     {
427       return droute_invalid_arguments_error (message);
428     }
429   ret = atk_table_is_row_selected (table, row);
430   reply = dbus_message_new_method_return (message);
431   if (reply)
432     {
433       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
434                                 DBUS_TYPE_INVALID);
435     }
436   return reply;
437 }
438
439 static DBusMessage *
440 impl_IsColumnSelected (DBusConnection * bus, DBusMessage * message,
441                        void *user_data)
442 {
443   AtkTable *table = (AtkTable *) user_data;
444   dbus_int32_t column;
445   DBusError error;
446   DBusMessage *reply;
447   dbus_bool_t ret;
448
449   g_return_val_if_fail (ATK_IS_TABLE (user_data),
450                         droute_not_yet_handled_error (message));
451   dbus_error_init (&error);
452   if (!dbus_message_get_args
453       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
454     {
455       return droute_invalid_arguments_error (message);
456     }
457   ret = atk_table_is_column_selected (table, column);
458   reply = dbus_message_new_method_return (message);
459   if (reply)
460     {
461       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
462                                 DBUS_TYPE_INVALID);
463     }
464   return reply;
465 }
466
467 static DBusMessage *
468 impl_IsSelected (DBusConnection * bus, DBusMessage * message, void *user_data)
469 {
470   AtkTable *table = (AtkTable *) user_data;
471   dbus_int32_t row, column;
472   DBusError error;
473   DBusMessage *reply;
474   dbus_bool_t ret;
475
476   g_return_val_if_fail (ATK_IS_TABLE (user_data),
477                         droute_not_yet_handled_error (message));
478   dbus_error_init (&error);
479   if (!dbus_message_get_args
480       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32, &column,
481        DBUS_TYPE_INVALID))
482     {
483       return droute_invalid_arguments_error (message);
484     }
485   ret = atk_table_is_selected (table, row, column);
486   reply = dbus_message_new_method_return (message);
487   if (reply)
488     {
489       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
490                                 DBUS_TYPE_INVALID);
491     }
492   return reply;
493 }
494
495 static DBusMessage *
496 impl_AddRowSelection (DBusConnection * bus, DBusMessage * message,
497                       void *user_data)
498 {
499   AtkTable *table = (AtkTable *) user_data;
500   dbus_int32_t row;
501   DBusError error;
502   DBusMessage *reply;
503   dbus_bool_t ret;
504
505   g_return_val_if_fail (ATK_IS_TABLE (user_data),
506                         droute_not_yet_handled_error (message));
507   dbus_error_init (&error);
508   if (!dbus_message_get_args
509       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
510     {
511       return droute_invalid_arguments_error (message);
512     }
513   ret = atk_table_add_row_selection (table, row);
514   reply = dbus_message_new_method_return (message);
515   if (reply)
516     {
517       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
518                                 DBUS_TYPE_INVALID);
519     }
520   return reply;
521 }
522
523 static DBusMessage *
524 impl_AddColumnSelection (DBusConnection * bus, DBusMessage * message,
525                          void *user_data)
526 {
527   AtkTable *table = (AtkTable *) user_data;
528   dbus_int32_t column;
529   DBusError error;
530   DBusMessage *reply;
531   dbus_bool_t ret;
532
533   g_return_val_if_fail (ATK_IS_TABLE (user_data),
534                         droute_not_yet_handled_error (message));
535   dbus_error_init (&error);
536   if (!dbus_message_get_args
537       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
538     {
539       return droute_invalid_arguments_error (message);
540     }
541   ret = atk_table_add_column_selection (table, column);
542   reply = dbus_message_new_method_return (message);
543   if (reply)
544     {
545       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
546                                 DBUS_TYPE_INVALID);
547     }
548   return reply;
549 }
550
551 static DBusMessage *
552 impl_RemoveRowSelection (DBusConnection * bus, DBusMessage * message,
553                          void *user_data)
554 {
555   AtkTable *table = (AtkTable *) user_data;
556   dbus_int32_t row;
557   DBusError error;
558   DBusMessage *reply;
559   dbus_bool_t ret;
560
561   g_return_val_if_fail (ATK_IS_TABLE (user_data),
562                         droute_not_yet_handled_error (message));
563   dbus_error_init (&error);
564   if (!dbus_message_get_args
565       (message, &error, DBUS_TYPE_INT32, &row, DBUS_TYPE_INVALID))
566     {
567       return droute_invalid_arguments_error (message);
568     }
569   ret = atk_table_remove_row_selection (table, row);
570   reply = dbus_message_new_method_return (message);
571   if (reply)
572     {
573       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
574                                 DBUS_TYPE_INVALID);
575     }
576   return reply;
577 }
578
579 static DBusMessage *
580 impl_RemoveColumnSelection (DBusConnection * bus, DBusMessage * message,
581                             void *user_data)
582 {
583   AtkTable *table = (AtkTable *) user_data;
584   dbus_int32_t column;
585   DBusError error;
586   DBusMessage *reply;
587   dbus_bool_t ret;
588
589   g_return_val_if_fail (ATK_IS_TABLE (user_data),
590                         droute_not_yet_handled_error (message));
591   dbus_error_init (&error);
592   if (!dbus_message_get_args
593       (message, &error, DBUS_TYPE_INT32, &column, DBUS_TYPE_INVALID))
594     {
595       return droute_invalid_arguments_error (message);
596     }
597   ret = atk_table_remove_column_selection (table, column);
598   reply = dbus_message_new_method_return (message);
599   if (reply)
600     {
601       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
602                                 DBUS_TYPE_INVALID);
603     }
604   return reply;
605 }
606
607 static DBusMessage *
608 impl_GetRowColumnExtentsAtIndex (DBusConnection * bus, DBusMessage * message,
609                                  void *user_data)
610 {
611   AtkTable *table = (AtkTable *) user_data;
612   dbus_int32_t index;
613   DBusError error;
614   dbus_int32_t row, column, row_extents, col_extents;
615   dbus_bool_t is_selected;
616   dbus_bool_t ret;
617   DBusMessage *reply;
618
619   AtkObject *cell;
620   AtkRole role;
621
622   g_return_val_if_fail (ATK_IS_TABLE (user_data),
623                         droute_not_yet_handled_error (message));
624   dbus_error_init (&error);
625   if (!dbus_message_get_args
626       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
627     {
628       return droute_invalid_arguments_error (message);
629     }
630   column = atk_table_get_column_at_index (table, index);
631   row = atk_table_get_row_at_index (table, index);
632   row_extents = atk_table_get_row_extent_at (table, row, column);
633   col_extents = atk_table_get_column_extent_at (table, row, column);
634   is_selected = atk_table_is_selected (table, row, column);
635   cell = atk_table_ref_at (table, row, column);
636   role = atk_object_get_role (cell);
637   g_object_unref (cell);
638   ret = (role == ATK_ROLE_TABLE_CELL ? TRUE : FALSE);
639   reply = dbus_message_new_method_return (message);
640   if (reply)
641     {
642       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
643                                 DBUS_TYPE_INT32, &row, DBUS_TYPE_INT32,
644                                 &column, DBUS_TYPE_INT32, &row_extents,
645                                 DBUS_TYPE_INT32, &col_extents,
646                                 DBUS_TYPE_BOOLEAN, &is_selected,
647                                 DBUS_TYPE_INVALID);
648     }
649   return reply;
650 }
651
652 static DRouteMethod methods[] = {
653   {impl_GetAccessibleAt, "GetAccessibleAt"},
654   {impl_GetIndexAt, "GetIndexAt"},
655   {impl_GetRowAtIndex, "GetRowAtIndex"},
656   {impl_GetColumnAtIndex, "GetColumnAtIndex"},
657   {impl_GetRowDescription, "GetRowDescription"},
658   {impl_GetColumnDescription, "GetColumnDescription"},
659   {impl_GetRowExtentAt, "GetRowExtentAt"},
660   {impl_GetColumnExtentAt, "GetColumnExtentAt"},
661   {impl_GetRowHeader, "GetRowHeader"},
662   {impl_GetColumnHeader, "GetColumnHeader"},
663   {impl_GetSelectedRows, "GetSelectedRows"},
664   {impl_GetSelectedColumns, "GetSelectedColumns"},
665   {impl_IsRowSelected, "IsRowSelected"},
666   {impl_IsColumnSelected, "IsColumnSelected"},
667   {impl_IsSelected, "IsSelected"},
668   {impl_AddRowSelection, "AddRowSelection"},
669   {impl_AddColumnSelection, "AddColumnSelection"},
670   {impl_RemoveRowSelection, "RemoveRowSelection"},
671   {impl_RemoveColumnSelection, "RemoveColumnSelection"},
672   {impl_GetRowColumnExtentsAtIndex, "GetRowColumnExtentsAtIndex"},
673   {NULL, NULL}
674 };
675
676 static DRouteProperty properties[] = {
677   {impl_get_NRows, NULL, "NRows"},
678   {impl_get_NColumns, NULL, "NColumns"},
679   {impl_get_Caption, NULL, "Caption"},
680   {impl_get_Summary, NULL, "Summary"},
681   {impl_get_NSelectedRows, NULL, "nSelectedRows"},
682   {impl_get_NSelectedColumns, NULL, "nSelectedColumns"},
683   {NULL, NULL, NULL}
684 };
685
686 void
687 spi_initialize_table (DRoutePath * path)
688 {
689   droute_path_add_interface (path,
690                              SPI_DBUS_INTERFACE_TABLE, spi_org_a11y_atspi_Table, methods, properties);
691 };