c893b49c3a43373b3a2186061b532d82109cb171
[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  * Not yet implemented.
32  *
33  **/
34 gboolean
35 atspi_collection_is_ancestor_of (AtspiCollection *collection,
36                                  AtspiAccessible *test,
37                                  GError **error)
38 {
39   g_warning ("Atspi: TODO: Implement is_ancestor_of");
40   return FALSE;
41 }
42
43 static DBusMessage *
44 new_message (AtspiCollection *collection, char *method)
45 {
46   AtspiAccessible *accessible;
47
48   if (!collection)
49     return NULL;
50
51   accessible = ATSPI_ACCESSIBLE (collection);
52   if (!accessible->parent.app)
53     return NULL;
54   return dbus_message_new_method_call (accessible->parent.app->bus_name,
55                                        accessible->parent.path,
56                                        atspi_interface_collection,
57                                        method);
58 }
59
60 static gboolean
61 append_match_rule (DBusMessage *message, AtspiMatchRule *rule)
62 {
63   DBusMessageIter iter;
64
65   dbus_message_iter_init_append (message, &iter);
66   return _atspi_match_rule_marshal (rule, &iter);
67 }
68
69 static gboolean
70 append_accessible (DBusMessage *message, AtspiAccessible *accessible)
71 {
72   DBusMessageIter iter;
73
74   dbus_message_iter_init_append (message, &iter);
75   dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH,
76                                   &accessible->parent.path);
77   return TRUE;  /* TODO: Check for out-of-memory */
78 }
79
80 static GArray *
81 return_accessibles (DBusMessage *message)
82 {
83   DBusMessageIter iter, iter_array;
84   GArray *ret;
85
86   _ATSPI_DBUS_CHECK_SIG (message, "a(so)", NULL, NULL);
87
88   ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
89
90   dbus_message_iter_init (message, &iter);
91   dbus_message_iter_recurse (&iter, &iter_array);
92
93   while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
94   {
95     AtspiAccessible *accessible;
96     accessible = _atspi_dbus_return_accessible_from_iter (&iter_array);
97     ret = g_array_append_val (ret, accessible);
98     /* Iter was moved already, so no need to call dbus_message_iter_next */
99   }
100   dbus_message_unref (message);
101   return ret;
102 }
103
104 /**
105  * atspi_collection_get_matches:
106  * @collection: A pointer to the #AtspiCollection to query.
107  * @rule: An #AtspiMatchRule describing the match criteria.
108  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
109  *          be sorted.
110  * @count: The maximum number of results to return, or 0 for no limit.
111  * @traverse: Not supported.
112  *
113  * Gets all #AtspiAccessible objects from the @collection matching a given
114  * @rule.  
115  *
116  * Returns: (element-type AtspiAccessible*) (transfer full): All 
117  *          #AtspiAccessible objects matching the given match rule.
118  **/
119 GArray *
120 atspi_collection_get_matches (AtspiCollection *collection,
121                               AtspiMatchRule *rule,
122                               AtspiCollectionSortOrder sortby,
123                               gint count,
124                               gboolean traverse,
125                               GError **error)
126 {
127   DBusMessage *message = new_message (collection, "GetMatches");
128   DBusMessage *reply;
129   dbus_int32_t d_sortby = sortby;
130   dbus_int32_t d_count = count;
131   dbus_bool_t d_traverse = traverse;
132
133   if (!message)
134     return NULL;
135
136   if (!append_match_rule (message, rule))
137     return NULL;
138   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
139                             DBUS_TYPE_INT32, &d_count,
140                             DBUS_TYPE_BOOLEAN, &d_traverse,
141                             DBUS_TYPE_INVALID);
142   reply = _atspi_dbus_send_with_reply_and_block (message, error);
143   if (!reply)
144     return NULL;
145   return return_accessibles (reply);
146 }
147
148 /**
149  * atspi_collection_get_matches_to:
150  * @collection: A pointer to the #AtspiCollection to query.
151  * @current_object: The object at which to start searching.
152  * @rule: An #AtspiMatchRule describing the match criteria.
153  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
154  *          be sorted.
155  * @tree: An #AtspiCollectionTreeTraversalType specifying restrictions on
156  *          the objects to be traversed.
157  * @limit_scope: If #TRUE, only descendants of @current_object's parent
158  *          will be returned. Otherwise (if #FALSE), any accessible may be
159  *          returned if it would preceed @current_object in a flattened
160  *          hierarchy.
161  * @count: The maximum number of results to return, or 0 for no limit.
162  * @traverse: Not supported.
163  *
164  * Gets all #AtspiAccessible objects from the @collection, after 
165  * @current_object, matching a given @rule.  
166  *
167  * Returns: (element-type AtspiAccessible*) (transfer full): All
168  *          #AtspiAccessible objects matching the given match rule after
169  *          @current_object.
170  **/
171 GArray *
172 atspi_collection_get_matches_to (AtspiCollection *collection,
173                               AtspiAccessible *current_object,
174                               AtspiMatchRule *rule,
175                               AtspiCollectionSortOrder sortby,
176                               AtspiCollectionTreeTraversalType tree,
177                               gboolean limit_scope,
178                               gint count,
179                               gboolean traverse,
180                               GError **error)
181 {
182   DBusMessage *message = new_message (collection, "GetMatchesTo");
183   DBusMessage *reply;
184   dbus_int32_t d_sortby = sortby;
185   dbus_int32_t d_tree = tree;
186   dbus_bool_t d_limit_scope = limit_scope;
187   dbus_int32_t d_count = count;
188   dbus_bool_t d_traverse = traverse;
189
190   if (!message)
191     return NULL;
192
193   if (!append_accessible (message, current_object))
194     return NULL;
195   if (!append_match_rule (message, rule))
196     return NULL;
197   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
198                                      DBUS_TYPE_UINT32, &d_tree,
199                             DBUS_TYPE_BOOLEAN, &d_limit_scope,
200                             DBUS_TYPE_INT32, &d_count,
201                             DBUS_TYPE_BOOLEAN, &d_traverse,
202                             DBUS_TYPE_INVALID);
203   reply = _atspi_dbus_send_with_reply_and_block (message, error);
204   if (!reply)
205     return NULL;
206   return return_accessibles (reply);
207 }
208
209 /**
210  * atspi_collection_get_matches_from:
211  * @collection: A pointer to the #AtspiCollection to query.
212  * @current_object: Upon reaching this object, searching should stop.
213  * @rule: An #AtspiMatchRule describing the match criteria.
214  * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
215  *          be sorted.
216  * @tree: An #AtspiCollectionTreeTraversalType specifying restrictions on
217  *          the objects to be traversed.
218  * @count: The maximum number of results to return, or 0 for no limit.
219  * @traverse: Not supported.
220  *
221  * Gets all #AtspiAccessible objects from the @collection, before  
222  * @current_object, matching a given @rule.  
223  *
224  * Returns: (element-type AtspiAccessible*) (transfer full): All 
225  *          #AtspiAccessible objects matching the given match rule that preceed
226  *          @current_object.
227  **/
228 GArray *
229 atspi_collection_get_matches_from (AtspiCollection *collection,
230                               AtspiAccessible *current_object,
231                               AtspiMatchRule *rule,
232                               AtspiCollectionSortOrder sortby,
233                               AtspiCollectionTreeTraversalType tree,
234                               gint count,
235                               gboolean traverse,
236                               GError **error)
237 {
238   DBusMessage *message = new_message (collection, "GetMatchesFrom");
239   DBusMessage *reply;
240   dbus_int32_t d_sortby = sortby;
241   dbus_int32_t d_tree = tree;
242   dbus_int32_t d_count = count;
243   dbus_bool_t d_traverse = traverse;
244
245   if (!message)
246     return NULL;
247
248   if (!append_accessible (message, current_object))
249     return NULL;
250   if (!append_match_rule (message, rule))
251     return NULL;
252   dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
253                             DBUS_TYPE_UINT32, &d_tree,
254                             DBUS_TYPE_INT32, &d_count,
255                             DBUS_TYPE_BOOLEAN, &d_traverse,
256                             DBUS_TYPE_INVALID);
257   reply = _atspi_dbus_send_with_reply_and_block (message, error);
258   if (!reply)
259     return NULL;
260   return return_accessibles (reply);
261 }
262
263 /**
264  * atspi_collection_get_active_descendant:
265  *
266 * Returns: (transfer full): The active descendant of the given object.
267  * Not yet implemented.
268  **/
269 AtspiAccessible *
270 atspi_collection_get_active_descendant (AtspiCollection *collection, GError **error)
271 {
272   g_warning ("atspi: TODO: Implement get_active_descendants");
273   return NULL;
274 }
275
276 static void
277 atspi_collection_base_init (AtspiCollection *klass)
278 {
279 }
280
281 GType
282 atspi_collection_get_type (void)
283 {
284   static GType type = 0;
285
286   if (!type) {
287     static const GTypeInfo tinfo =
288     {
289       sizeof (AtspiCollection),
290       (GBaseInitFunc) atspi_collection_base_init,
291       (GBaseFinalizeFunc) NULL,
292     };
293
294     type = g_type_register_static (G_TYPE_INTERFACE, "AtspiCollection", &tinfo, 0);
295
296   }
297   return type;
298 }