2008-05-16 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / selection.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 AtkSelection *
28 get_selection (DBusMessage * message)
29 {
30   AtkObject *obj = spi_dbus_get_object (dbus_message_get_path (message));
31   if (!obj)
32     return NULL;
33   return ATK_SELECTION (obj);
34 }
35
36 static AtkSelection *
37 get_selection_from_path (const char *path, void *user_data)
38 {
39   AtkObject *obj = spi_dbus_get_object (path);
40   if (!obj || ~ATK_IS_SELECTION(obj))
41     return NULL;
42   return ATK_SELECTION (obj);
43 }
44
45 static dbus_bool_t
46 impl_get_nSelectedChildren (const char *path, DBusMessageIter * iter,
47                             void *user_data)
48 {
49   AtkSelection *selection = get_selection_from_path (path, user_data);
50   if (!selection)
51     return FALSE;
52   return droute_return_v_int32 (iter,
53                                 atk_selection_get_selection_count
54                                 (selection));
55 }
56
57 static char *
58 impl_get_nSelectedChildren_str (void *datum)
59 {
60   g_assert (ATK_IS_HYPERLINK (datum));
61   return g_strdup_printf ("%d",
62                           atk_selection_get_selection_count ((AtkSelection *)
63                                                              datum));
64 }
65
66 static DBusMessage *
67 impl_getSelectedChild (DBusConnection * bus, DBusMessage * message,
68                        void *user_data)
69 {
70   AtkSelection *selection = get_selection (message);
71   DBusError error;
72   dbus_int32_t selectedChildIndex;
73   AtkObject *atk_object;
74
75   if (!selection)
76     return spi_dbus_general_error (message);
77   dbus_error_init (&error);
78   if (!dbus_message_get_args
79       (message, &error, DBUS_TYPE_INT32, &selectedChildIndex,
80        DBUS_TYPE_INVALID))
81     {
82       return SPI_DBUS_RETURN_ERROR (message, &error);
83     }
84   atk_object = atk_selection_ref_selection (selection, selectedChildIndex);
85   return spi_dbus_return_object (message, atk_object, TRUE);
86 }
87
88 static DBusMessage *
89 impl_selectChild (DBusConnection * bus, DBusMessage * message,
90                   void *user_data)
91 {
92   AtkSelection *selection = get_selection (message);
93   DBusError error;
94   dbus_int32_t childIndex;
95   dbus_bool_t rv;
96   DBusMessage *reply;
97
98   if (!selection)
99     return spi_dbus_general_error (message);
100   dbus_error_init (&error);
101   if (!dbus_message_get_args
102       (message, &error, DBUS_TYPE_INT32, &childIndex, DBUS_TYPE_INVALID))
103     {
104       return SPI_DBUS_RETURN_ERROR (message, &error);
105     }
106   rv = atk_selection_add_selection (selection, childIndex);
107   reply = dbus_message_new_method_return (message);
108   if (reply)
109     {
110       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
111                                 DBUS_TYPE_INVALID);
112     }
113   return reply;
114 }
115
116 static DBusMessage *
117 impl_deselectSelectedChild (DBusConnection * bus, DBusMessage * message,
118                             void *user_data)
119 {
120   AtkSelection *selection = get_selection (message);
121   DBusError error;
122   dbus_int32_t selectedChildIndex;
123   dbus_bool_t rv;
124   DBusMessage *reply;
125
126   if (!selection)
127     return spi_dbus_general_error (message);
128   dbus_error_init (&error);
129   if (!dbus_message_get_args
130       (message, &error, DBUS_TYPE_INT32, &selectedChildIndex,
131        DBUS_TYPE_INVALID))
132     {
133       return SPI_DBUS_RETURN_ERROR (message, &error);
134     }
135   rv = atk_selection_remove_selection (selection, selectedChildIndex);
136   reply = dbus_message_new_method_return (message);
137   if (reply)
138     {
139       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
140                                 DBUS_TYPE_INVALID);
141     }
142   return reply;
143 }
144
145 static DBusMessage *
146 impl_isChildSelected (DBusConnection * bus, DBusMessage * message,
147                       void *user_data)
148 {
149   AtkSelection *selection = get_selection (message);
150   DBusError error;
151   dbus_int32_t childIndex;
152   dbus_bool_t rv;
153   DBusMessage *reply;
154
155   if (!selection)
156     return spi_dbus_general_error (message);
157   dbus_error_init (&error);
158   if (!dbus_message_get_args
159       (message, &error, DBUS_TYPE_INT32, &childIndex, DBUS_TYPE_INVALID))
160     {
161       return SPI_DBUS_RETURN_ERROR (message, &error);
162     }
163   rv = atk_selection_is_child_selected (selection, childIndex);
164   reply = dbus_message_new_method_return (message);
165   if (reply)
166     {
167       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
168                                 DBUS_TYPE_INVALID);
169     }
170   return reply;
171 }
172
173 static DBusMessage *
174 impl_selectAll (DBusConnection * bus, DBusMessage * message, void *user_data)
175 {
176   AtkSelection *selection = get_selection (message);
177   dbus_bool_t rv;
178   DBusMessage *reply;
179
180   if (!selection)
181     return spi_dbus_general_error (message);
182   rv = atk_selection_select_all_selection (selection);
183   reply = dbus_message_new_method_return (message);
184   if (reply)
185     {
186       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
187                                 DBUS_TYPE_INVALID);
188     }
189   return reply;
190 }
191
192 static DBusMessage *
193 impl_clearSelection (DBusConnection * bus, DBusMessage * message,
194                      void *user_data)
195 {
196   AtkSelection *selection = get_selection (message);
197   dbus_bool_t rv;
198   DBusMessage *reply;
199
200   if (!selection)
201     return spi_dbus_general_error (message);
202   rv = atk_selection_clear_selection (selection);
203   reply = dbus_message_new_method_return (message);
204   if (reply)
205     {
206       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
207                                 DBUS_TYPE_INVALID);
208     }
209   return reply;
210 }
211
212 static DBusMessage *
213 impl_deselectChild (DBusConnection * bus, DBusMessage * message,
214                     void *user_data)
215 {
216   AtkSelection *selection = get_selection (message);
217   DBusError error;
218   dbus_int32_t selectedChildIndex;
219   dbus_bool_t rv = FALSE;
220   gint i, nselected;
221   DBusMessage *reply;
222
223   if (!selection)
224     return spi_dbus_general_error (message);
225   dbus_error_init (&error);
226   if (!dbus_message_get_args
227       (message, &error, DBUS_TYPE_INT32, &selectedChildIndex,
228        DBUS_TYPE_INVALID))
229     {
230       return SPI_DBUS_RETURN_ERROR (message, &error);
231     }
232   nselected = atk_selection_get_selection_count (selection);
233   for (i = 0; i < nselected; ++i)
234     {
235       AtkObject *selected_obj = atk_selection_ref_selection (selection, i);
236       if (atk_object_get_index_in_parent (selected_obj) == selectedChildIndex)
237         {
238           g_object_unref (G_OBJECT (selected_obj));
239           rv = atk_selection_remove_selection (selection, i);
240           break;
241         }
242       g_object_unref (G_OBJECT (selected_obj));
243     }
244   reply = dbus_message_new_method_return (message);
245   if (reply)
246     {
247       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
248                                 DBUS_TYPE_INVALID);
249     }
250   return reply;
251 }
252
253 static DRouteMethod methods[] = {
254   {impl_getSelectedChild, "getSelectedChild"},
255   {impl_selectChild, "selectChild"},
256   {impl_deselectSelectedChild, "deselectSelectedChild"},
257   {impl_isChildSelected, "isChildSelected"},
258   {impl_selectAll, "selectAll"},
259   {impl_clearSelection, "clearSelection"},
260   {impl_deselectChild, "deselectChild"},
261   {NULL, NULL}
262 };
263
264 static DRouteProperty properties[] = {
265   {impl_get_nSelectedChildren, NULL, "nSelectedChildren"},
266   {NULL, NULL, NULL}
267 };
268
269 void
270 spi_initialize_selection (DRouteData * data)
271 {
272   droute_add_interface (data, "org.freedesktop.atspi.Selection",
273                         methods, properties,
274                         (DRouteGetDatumFunction) get_selection_from_path,
275                         NULL);
276 };