2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2008 Novell, Inc.
6 * Copyright 2001, 2002 Sun Microsystems Inc.,
7 * Copyright 2001, 2002 Ximian, Inc.
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.
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.
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.
25 #include "accessible.h"
28 get_table (DBusMessage * message)
30 AtkObject *obj = spi_dbus_get_object (dbus_message_get_path (message));
33 return ATK_TABLE (obj);
37 get_table_from_path (const char *path, void *user_data)
39 AtkObject *obj = spi_dbus_get_object (path);
42 return ATK_TABLE (obj);
46 impl_get_nRows (const char *path, DBusMessageIter * iter, void *user_data)
48 AtkTable *table = get_table_from_path (path, user_data);
51 return droute_return_v_int32 (iter, atk_table_get_n_rows (table));
55 impl_get_nRows_str (void *datum)
57 g_assert (ATK_IS_TABLE (datum));
58 return g_strdup_printf ("%d", atk_table_get_n_rows ((AtkTable *) datum));
62 impl_get_nColumns (const char *path, DBusMessageIter * iter, void *user_data)
64 AtkTable *table = get_table_from_path (path, user_data);
67 return droute_return_v_int32 (iter, atk_table_get_n_columns (table));
71 impl_get_nColumns_str (void *datum)
73 g_assert (ATK_IS_TABLE (datum));
74 return g_strdup_printf ("%d", atk_table_get_n_columns ((AtkTable *) datum));
78 impl_get_caption (const char *path, DBusMessageIter * iter, void *user_data)
80 AtkTable *table = get_table_from_path (path, user_data);
83 return spi_dbus_return_v_object (iter, atk_table_get_caption (table),
88 impl_get_caption_str (void *datum)
90 AtkTable *table = (AtkTable *) datum;
91 g_assert (ATK_IS_TABLE (datum));
92 return spi_dbus_get_path (atk_table_get_caption (table));
96 impl_get_summary (const char *path, DBusMessageIter * iter, void *user_data)
98 AtkTable *table = get_table_from_path (path, user_data);
101 return spi_dbus_return_v_object (iter, atk_table_get_summary (table),
106 impl_get_summary_str (void *datum)
108 AtkTable *table = (AtkTable *) datum;
109 g_assert (ATK_IS_TABLE (datum));
110 return spi_dbus_get_path (atk_table_get_summary (table));
114 impl_get_nSelectedRows (const char *path, DBusMessageIter * iter,
117 AtkTable *table = get_table_from_path (path, user_data);
118 gint *selected_rows = NULL;
122 count = atk_table_get_selected_rows (table, &selected_rows);
124 g_free (selected_rows);
125 return droute_return_v_int32 (iter, count);
129 impl_get_nSelectedRows_str (void *datum)
132 gint *selected_rows = NULL;
133 g_assert (ATK_IS_TABLE (datum));
134 count = atk_table_get_selected_rows ((AtkTable *) datum, &selected_rows);
136 g_free (selected_rows);
137 return g_strdup_printf ("%d", count);
141 impl_get_nSelectedColumns (const char *path, DBusMessageIter * iter,
144 AtkTable *table = get_table_from_path (path, user_data);
145 gint *selected_columns = NULL;
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);
156 impl_get_nSelectedColumns_str (void *datum)
159 gint *selected_columns = NULL;
160 g_assert (ATK_IS_TABLE (datum));
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);
170 impl_getAccessibleAt (DBusConnection * bus, DBusMessage * message,
173 AtkTable *table = get_table (message);
174 dbus_int32_t row, column;
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,
185 return SPI_DBUS_RETURN_ERROR (message, &error);
187 obj = atk_table_ref_at (table, row, column);
188 return spi_dbus_return_object (message, obj, TRUE);
192 impl_getIndexAt (DBusConnection * bus, DBusMessage * message, void *user_data)
194 AtkTable *table = get_table (message);
195 dbus_int32_t row, column;
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,
207 return SPI_DBUS_RETURN_ERROR (message, &error);
209 index = atk_table_get_index_at (table, row, column);
210 reply = dbus_message_new_method_return (message);
213 dbus_message_append_args (reply, DBUS_TYPE_INT32, &index,
220 impl_getRowAtIndex (DBusConnection * bus, DBusMessage * message,
223 AtkTable *table = get_table (message);
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))
235 return SPI_DBUS_RETURN_ERROR (message, &error);
237 row = atk_table_get_row_at_index (table, index);
238 reply = dbus_message_new_method_return (message);
241 dbus_message_append_args (reply, DBUS_TYPE_INT32, &row,
248 impl_getColumnAtIndex (DBusConnection * bus, DBusMessage * message,
251 AtkTable *table = get_table (message);
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))
263 return SPI_DBUS_RETURN_ERROR (message, &error);
265 column = atk_table_get_column_at_index (table, index);
266 reply = dbus_message_new_method_return (message);
269 dbus_message_append_args (reply, DBUS_TYPE_INT32, &column,
276 impl_getRowDescription (DBusConnection * bus, DBusMessage * message,
279 AtkTable *table = get_table (message);
281 const gchar *description;
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))
291 return SPI_DBUS_RETURN_ERROR (message, &error);
293 description = atk_table_get_row_description (table, row);
296 reply = dbus_message_new_method_return (message);
299 dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
306 impl_getColumnDescription (DBusConnection * bus, DBusMessage * message,
309 AtkTable *table = get_table (message);
311 const char *description;
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))
321 return SPI_DBUS_RETURN_ERROR (message, &error);
323 description = atk_table_get_column_description (table, column);
326 reply = dbus_message_new_method_return (message);
329 dbus_message_append_args (reply, DBUS_TYPE_STRING, &description,
336 impl_getRowExtentAt (DBusConnection * bus, DBusMessage * message,
339 AtkTable *table = get_table (message);
340 dbus_int32_t row, column;
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,
352 return SPI_DBUS_RETURN_ERROR (message, &error);
354 extent = atk_table_get_row_extent_at (table, row, column);
355 reply = dbus_message_new_method_return (message);
358 dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
365 impl_getColumnExtentAt (DBusConnection * bus, DBusMessage * message,
368 AtkTable *table = get_table (message);
369 dbus_int32_t row, column;
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,
381 return SPI_DBUS_RETURN_ERROR (message, &error);
383 extent = atk_table_get_column_extent_at (table, row, column);
384 reply = dbus_message_new_method_return (message);
387 dbus_message_append_args (reply, DBUS_TYPE_INT32, &extent,
394 impl_getRowHeader (DBusConnection * bus, DBusMessage * message,
397 AtkTable *table = get_table (message);
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))
408 return SPI_DBUS_RETURN_ERROR (message, &error);
410 obj = atk_table_get_row_header (table, row);
411 return spi_dbus_return_object (message, obj, FALSE);
415 impl_getColumnHeader (DBusConnection * bus, DBusMessage * message,
418 AtkTable *table = get_table (message);
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))
429 return SPI_DBUS_RETURN_ERROR (message, &error);
431 obj = atk_table_get_column_header (table, column);
432 return spi_dbus_return_object (message, obj, FALSE);
436 impl_getSelectedRows (DBusConnection * bus, DBusMessage * message,
439 AtkTable *table = get_table (message);
440 gint *selected_rows = NULL;
445 return spi_dbus_general_error (message);
446 count = atk_table_get_selected_rows (table, &selected_rows);
449 reply = dbus_message_new_method_return (message);
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);
457 g_free (selected_rows);
462 impl_getSelectedColumns (DBusConnection * bus, DBusMessage * message,
465 AtkTable *table = get_table (message);
466 gint *selected_columns = NULL;
471 return spi_dbus_general_error (message);
472 count = atk_table_get_selected_columns (table, &selected_columns);
473 if (!selected_columns)
475 reply = dbus_message_new_method_return (message);
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);
482 if (selected_columns)
483 g_free (selected_columns);
488 impl_isRowSelected (DBusConnection * bus, DBusMessage * message,
491 AtkTable *table = get_table (message);
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))
503 return SPI_DBUS_RETURN_ERROR (message, &error);
505 ret = atk_table_is_row_selected (table, row);
506 reply = dbus_message_new_method_return (message);
509 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
516 impl_isColumnSelected (DBusConnection * bus, DBusMessage * message,
519 AtkTable *table = get_table (message);
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))
531 return SPI_DBUS_RETURN_ERROR (message, &error);
533 ret = atk_table_is_column_selected (table, column);
534 reply = dbus_message_new_method_return (message);
537 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
544 impl_isSelected (DBusConnection * bus, DBusMessage * message, void *user_data)
546 AtkTable *table = get_table (message);
547 dbus_int32_t row, column;
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,
559 return SPI_DBUS_RETURN_ERROR (message, &error);
561 ret = atk_table_is_selected (table, row, column);
562 reply = dbus_message_new_method_return (message);
565 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
572 impl_addRowSelection (DBusConnection * bus, DBusMessage * message,
575 AtkTable *table = get_table (message);
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))
587 return SPI_DBUS_RETURN_ERROR (message, &error);
589 ret = atk_table_add_row_selection (table, row);
590 reply = dbus_message_new_method_return (message);
593 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
600 impl_addColumnSelection (DBusConnection * bus, DBusMessage * message,
603 AtkTable *table = get_table (message);
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))
615 return SPI_DBUS_RETURN_ERROR (message, &error);
617 ret = atk_table_add_column_selection (table, column);
618 reply = dbus_message_new_method_return (message);
621 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
628 impl_removeRowSelection (DBusConnection * bus, DBusMessage * message,
631 AtkTable *table = get_table (message);
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))
643 return SPI_DBUS_RETURN_ERROR (message, &error);
645 ret = atk_table_remove_row_selection (table, row);
646 reply = dbus_message_new_method_return (message);
649 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
656 impl_removeColumnSelection (DBusConnection * bus, DBusMessage * message,
659 AtkTable *table = get_table (message);
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))
671 return SPI_DBUS_RETURN_ERROR (message, &error);
673 ret = atk_table_remove_column_selection (table, column);
674 reply = dbus_message_new_method_return (message);
677 dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &ret,
684 impl_getRowColumnExtentsAtIndex (DBusConnection * bus, DBusMessage * message,
687 AtkTable *table = get_table (message);
690 dbus_int32_t row, column, row_extents, col_extents;
691 dbus_bool_t is_selected;
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))
704 return SPI_DBUS_RETURN_ERROR (message, &error);
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);
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);
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",
734 {DROUTE_METHOD, impl_getRowDescription, "getRowDescription",
736 {DROUTE_METHOD, impl_getColumnDescription, "getColumnDescription",
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",
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",
753 {DROUTE_METHOD, impl_removeRowSelection, "removeRowSelection",
755 {DROUTE_METHOD, impl_removeColumnSelection, "removeColumnSelection",
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}
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}
776 spi_initialize_table (DRouteData * data)
778 droute_add_interface (data, "org.freedesktop.accessibility.Table", methods,
780 (DRouteGetDatumFunction) get_table_from_path, NULL);