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