Starting to improve atspi-collection
[platform/upstream/at-spi2-core.git] / atspi / atspi-collection.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2007 IBM Corp.
6  * Copyright 2010, 2011 Novell, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include "atspi-private.h"
25
26 /* TODO: Improve documentation and implement some missing functions */
27
28 /**
29  * atspi_collection_is_ancestor_of:
30  *
31  * @collection: A pointer to the #AtspiCollection to test against.
32  * @test: The #AtspiAccessible to test.
33  *
34  * Not yet implemented. 
35  *
36  * Returns: TRUE if @collection is an ancestor of @test; FALSE otherwise.
37  *
38  **/
39 gboolean
40 atspi_collection_is_ancestor_of (AtspiCollection *collection,
41                                  AtspiAccessible *test,
42                                  GError **error)
43 {
44   g_warning ("Atspi: TODO: Implement is_ancestor_of");
45   return FALSE;
46 }
47
48 static DBusMessage *
49 new_message (AtspiCollection *collection, char *method)
50 {
51   AtspiAccessible *accessible;
52
53   if (!collection)
54     return NULL;
55
56   accessible = ATSPI_ACCESSIBLE (collection);
57   return dbus_message_new_method_call (accessible->parent.app->bus_name,
58                                        accessible->parent.path,
59                                        atspi_interface_collection,
60                                        method);
61 }
62
63 static gboolean
64 append_match_rule (DBusMessage *message, AtspiMatchRule *rule)
65 {
66   DBusMessageIter iter;
67
68   dbus_message_iter_init_append (message, &iter);
69   return _atspi_match_rule_marshal (rule, &iter);
70 }
71
72 static gboolean
73 append_accessible (DBusMessage *message, AtspiAccessible *accessible)
74 {
75   DBusMessageIter iter;
76
77   dbus_message_iter_init_append (message, &iter);
78   dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH,
79                                   &accessible->parent.path);
80   return TRUE;  /* TODO: Check for out-of-memory */
81 }
82
83 static GArray *
84 return_accessibles (DBusMessage *message)
85 {
86   DBusMessageIter iter, iter_array;
87   GArray *ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
88
89   _ATSPI_DBUS_CHECK_SIG (message, "a(so)", NULL, NULL);
90
91   dbus_message_iter_init (message, &iter);
92   dbus_message_iter_recurse (&iter, &iter_array);
93
94   while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
95   {
96     AtspiAccessible *accessible;
97     GArray *new_array;
98     accessible = _atspi_dbus_return_accessible_from_iter (&iter_array);
99     new_array = g_array_append_val (ret, accessible);
100     if (new_array)
101       ret = new_array;
102     /* Iter was moved already, so no need to call dbus_message_iter_next */
103   }
104   dbus_message_unref (message);
105   return ret;
106 }
107
108 /**
109  * atspi_collection_get_matches:
110  *
111  * @collection: A pointer to the #AtspiCollection to query.
112  * @rule: An #AtspiMatchRule describing the match criteria.
113  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
114  *          be sorted.
115  * @count: The maximum number of results to return, or 0 for no limit.
116  * @traverse: TODO
117  *
118  * Returns: (element-type AtspiAccessible*) (transfer full): A #GArray of
119  *          #AtspiAccessibles matching the given match rule.
120  **/
121 GArray *
122 atspi_collection_get_matches (AtspiCollection *collection,
123                               AtspiMatchRule *rule,
124                               AtspiCollectionSortOrder sortby,
125                               gint count,
126                               gboolean traverse,
127                               GError **error)
128 {
129   DBusMessage *message = new_message (collection, "GetMatches");
130   DBusMessage *reply;
131   dbus_int32_t d_sortby = sortby;
132   dbus_int32_t d_count = count;
133   dbus_bool_t d_traverse = traverse;
134
135   if (!message)
136     return NULL;
137
138   if (!append_match_rule (message, rule))
139     return NULL;
140   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
141                             DBUS_TYPE_INT32, &d_count,
142                             DBUS_TYPE_BOOLEAN, &d_traverse,
143                             DBUS_TYPE_INVALID);
144   reply = _atspi_dbus_send_with_reply_and_block (message, error);
145   if (!reply)
146     return NULL;
147   return return_accessibles (reply);
148 }
149
150 /**
151  * atspi_collection_get_matches_to:
152  *
153  * @collection: A pointer to the #AtspiCollection to query.
154  * @current_object: The object at which to start searching.
155  * @rule: An #AtspiMatchRule describing the match criteria.
156  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
157  *          be sorted.
158  * @tree: An #AtspiCollectionTreeTraversalType specifying restrictions on
159  *        the objects to be traversed.
160  * @recurse: TODO
161  * @count: The maximum number of results to return, or 0 for no limit.
162  * @traverse: TODO
163  *
164  * Returns: (element-type AtspiAccessible*) (transfer full): A #GArray of
165  *          #AtspiAccessibles matching the given match rule after
166  *          @current_object.
167  **/
168 GArray *
169 atspi_collection_get_matches_to (AtspiCollection *collection,
170                               AtspiAccessible *current_object,
171                               AtspiMatchRule *rule,
172                               AtspiCollectionSortOrder sortby,
173                               AtspiCollectionTreeTraversalType tree,
174                               gboolean recurse,
175                               gint count,
176                               gboolean traverse,
177                               GError **error)
178 {
179   DBusMessage *message = new_message (collection, "GetMatchesTo");
180   DBusMessage *reply;
181   dbus_int32_t d_sortby = sortby;
182   dbus_int32_t d_tree = tree;
183   dbus_bool_t d_recurse = recurse;
184   dbus_int32_t d_count = count;
185   dbus_bool_t d_traverse = traverse;
186
187   if (!message)
188     return NULL;
189
190   if (!append_accessible (message, current_object))
191     return NULL;
192   if (!append_match_rule (message, rule))
193     return NULL;
194   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
195                                      DBUS_TYPE_UINT32, &d_tree,
196                             DBUS_TYPE_BOOLEAN, &d_recurse,
197                             DBUS_TYPE_INT32, &d_count,
198                             DBUS_TYPE_BOOLEAN, &d_traverse,
199                             DBUS_TYPE_INVALID);
200   reply = _atspi_dbus_send_with_reply_and_block (message, error);
201   if (!reply)
202     return NULL;
203   return return_accessibles (reply);
204 }
205
206 /**
207  * atspi_collection_get_matches_from:
208  *
209  * @collection: A pointer to the #AtspiCollection to query.
210  * @current_object: Upon reaching this object, searching should stop.
211  * @rule: An #AtspiMatchRule describing the match criteria.
212  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
213  *          be sorted.
214  * @tree: An #AtspiCollectionTreeTraversalType specifying restrictions on
215  *        the objects to be traversed.
216  * @count: The maximum number of results to return, or 0 for no limit.
217  * @traverse: TODO
218  *
219  * Returns: (element-type AtspiAccessible*) (transfer full): A #GArray of
220  *          #AtspiAccessibles matching the given match rule that preceed
221  *          @current_object.
222  **/
223 GArray *
224 atspi_collection_get_matches_from (AtspiCollection *collection,
225                               AtspiAccessible *current_object,
226                               AtspiMatchRule *rule,
227                               AtspiCollectionSortOrder sortby,
228                               AtspiCollectionTreeTraversalType tree,
229                               gint count,
230                               gboolean traverse,
231                               GError **error)
232 {
233   DBusMessage *message = new_message (collection, "GetMatchesFrom");
234   DBusMessage *reply;
235   dbus_int32_t d_sortby = sortby;
236   dbus_int32_t d_tree = tree;
237   dbus_int32_t d_count = count;
238   dbus_bool_t d_traverse = traverse;
239
240   if (!message)
241     return NULL;
242
243   if (!append_accessible (message, current_object))
244     return NULL;
245   if (!append_match_rule (message, rule))
246     return NULL;
247   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
248                             DBUS_TYPE_UINT32, &d_tree,
249                             DBUS_TYPE_INT32, &d_count,
250                             DBUS_TYPE_BOOLEAN, &d_traverse,
251                             DBUS_TYPE_INVALID);
252   reply = _atspi_dbus_send_with_reply_and_block (message, error);
253   if (!reply)
254     return NULL;
255   return return_accessibles (reply);
256 }
257
258 /**
259  * atspi_collection_get_active_descendant:
260  * 
261   @collection: A pointer to the #AtspiCollection to query.
262  *
263  * Returns: (transfer full): The active descendant of #collection.
264  *
265  * Not yet implemented.
266  **/
267 AtspiAccessible *
268 atspi_collection_get_active_descendant (AtspiCollection *collection, GError **error)
269 {
270   g_warning ("atspi: TODO: Implement get_active_descendants");
271   return NULL;
272 }
273
274 static void
275 atspi_collection_base_init (AtspiCollection *klass)
276 {
277 }
278
279 GType
280 atspi_collection_get_type (void)
281 {
282   static GType type = 0;
283
284   if (!type) {
285     static const GTypeInfo tinfo =
286     {
287       sizeof (AtspiCollection),
288       (GBaseInitFunc) atspi_collection_base_init,
289       (GBaseFinalizeFunc) NULL,
290     };
291
292     type = g_type_register_static (G_TYPE_INTERFACE, "AtspiCollection", &tinfo, 0);
293
294   }
295   return type;
296 }