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 Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 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 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, 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
atspi_collection_is_ancestor_of(AtspiCollection * collection,AtspiAccessible * test,GError ** error)35 atspi_collection_is_ancestor_of (AtspiCollection *collection,
36 AtspiAccessible *test,
37 GError **error)
38 {
39 g_warning ("AT-SPI: TODO: Implement is_ancestor_of");
40 return FALSE;
41 }
42
43 static DBusMessage *
new_message(AtspiCollection * collection,char * method)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
append_match_rule(DBusMessage * message,AtspiMatchRule * rule)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
append_accessible(DBusMessage * message,AtspiAccessible * accessible)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 *
return_accessibles(DBusMessage * message)81 return_accessibles (DBusMessage *message)
82 {
83 DBusMessageIter iter, iter_array;
84 GArray *ret = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
85
86 _ATSPI_DBUS_CHECK_SIG (message, "a(so)", NULL, NULL);
87
88 dbus_message_iter_init (message, &iter);
89 dbus_message_iter_recurse (&iter, &iter_array);
90
91 while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
92 {
93 AtspiAccessible *accessible;
94 accessible = _atspi_dbus_return_accessible_from_iter (&iter_array);
95 ret = g_array_append_val (ret, accessible);
96 /* Iter was moved already, so no need to call dbus_message_iter_next */
97 }
98 dbus_message_unref (message);
99 return ret;
100 }
101
102 /**
103 * atspi_collection_get_matches:
104 * @collection: A pointer to the #AtspiCollection to query.
105 * @rule: An #AtspiMatchRule describing the match criteria.
106 * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
107 * be sorted.
108 * @count: The maximum number of results to return, or 0 for no limit.
109 * @traverse: Not supported.
110 *
111 * Gets all #AtspiAccessible objects from the @collection matching a given
112 * @rule.
113 *
114 * Returns: (element-type AtspiAccessible*) (transfer full): All
115 * #AtspiAccessible objects matching the given match rule.
116 **/
117 GArray *
atspi_collection_get_matches(AtspiCollection * collection,AtspiMatchRule * rule,AtspiCollectionSortOrder sortby,gint count,gboolean traverse,GError ** error)118 atspi_collection_get_matches (AtspiCollection *collection,
119 AtspiMatchRule *rule,
120 AtspiCollectionSortOrder sortby,
121 gint count,
122 gboolean traverse,
123 GError **error)
124 {
125 DBusMessage *message = new_message (collection, "GetMatches");
126 DBusMessage *reply;
127 dbus_int32_t d_sortby = sortby;
128 dbus_int32_t d_count = count;
129 dbus_bool_t d_traverse = traverse;
130
131 if (!message)
132 return NULL;
133
134 if (!append_match_rule (message, rule))
135 return NULL;
136 dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
137 DBUS_TYPE_INT32, &d_count,
138 DBUS_TYPE_BOOLEAN, &d_traverse,
139 DBUS_TYPE_INVALID);
140 reply = _atspi_dbus_send_with_reply_and_block (message, error);
141 if (!reply)
142 return NULL;
143 return return_accessibles (reply);
144 }
145
146 /**
147 * atspi_collection_get_matches_to:
148 * @collection: A pointer to the #AtspiCollection to query.
149 * @current_object: The object at which to start searching.
150 * @rule: An #AtspiMatchRule describing the match criteria.
151 * @sortby: An #AtspiCollectionSortOrder specifying the way the results are to
152 * be sorted.
153 * @tree: An #AtspiCollectionTreeTraversalType specifying restrictions on
154 * the objects to be traversed.
155 * @limit_scope: If #TRUE, only descendants of @current_object's parent
156 * will be returned. Otherwise (if #FALSE), any accessible may be
157 * returned if it would preceed @current_object in a flattened
158 * hierarchy.
159 * @count: The maximum number of results to return, or 0 for no limit.
160 * @traverse: Not supported.
161 *
162 * Gets all #AtspiAccessible objects from the @collection, after
163 * @current_object, matching a given @rule.
164 *
165 * Returns: (element-type AtspiAccessible*) (transfer full): All
166 * #AtspiAccessible objects matching the given match rule after
167 * @current_object.
168 **/
169 GArray *
atspi_collection_get_matches_to(AtspiCollection * collection,AtspiAccessible * current_object,AtspiMatchRule * rule,AtspiCollectionSortOrder sortby,AtspiCollectionTreeTraversalType tree,gboolean limit_scope,gint count,gboolean traverse,GError ** error)170 atspi_collection_get_matches_to (AtspiCollection *collection,
171 AtspiAccessible *current_object,
172 AtspiMatchRule *rule,
173 AtspiCollectionSortOrder sortby,
174 AtspiCollectionTreeTraversalType tree,
175 gboolean limit_scope,
176 gint count,
177 gboolean traverse,
178 GError **error)
179 {
180 DBusMessage *message = new_message (collection, "GetMatchesTo");
181 DBusMessage *reply;
182 dbus_int32_t d_sortby = sortby;
183 dbus_int32_t d_tree = tree;
184 dbus_bool_t d_limit_scope = limit_scope;
185 dbus_int32_t d_count = count;
186 dbus_bool_t d_traverse = traverse;
187
188 if (!message)
189 return NULL;
190
191 if (!append_accessible (message, current_object))
192 return NULL;
193 if (!append_match_rule (message, rule))
194 return NULL;
195 dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
196 DBUS_TYPE_UINT32, &d_tree,
197 DBUS_TYPE_BOOLEAN, &d_limit_scope,
198 DBUS_TYPE_INT32, &d_count,
199 DBUS_TYPE_BOOLEAN, &d_traverse,
200 DBUS_TYPE_INVALID);
201 reply = _atspi_dbus_send_with_reply_and_block (message, error);
202 if (!reply)
203 return NULL;
204 return return_accessibles (reply);
205 }
206
207 /**
208 * atspi_collection_get_matches_from:
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: Not supported.
218 *
219 * Gets all #AtspiAccessible objects from the @collection, before
220 * @current_object, matching a given @rule.
221 *
222 * Returns: (element-type AtspiAccessible*) (transfer full): All
223 * #AtspiAccessible objects matching the given match rule that preceed
224 * @current_object.
225 **/
226 GArray *
atspi_collection_get_matches_from(AtspiCollection * collection,AtspiAccessible * current_object,AtspiMatchRule * rule,AtspiCollectionSortOrder sortby,AtspiCollectionTreeTraversalType tree,gint count,gboolean traverse,GError ** error)227 atspi_collection_get_matches_from (AtspiCollection *collection,
228 AtspiAccessible *current_object,
229 AtspiMatchRule *rule,
230 AtspiCollectionSortOrder sortby,
231 AtspiCollectionTreeTraversalType tree,
232 gint count,
233 gboolean traverse,
234 GError **error)
235 {
236 DBusMessage *message = new_message (collection, "GetMatchesFrom");
237 DBusMessage *reply;
238 dbus_int32_t d_sortby = sortby;
239 dbus_int32_t d_tree = tree;
240 dbus_int32_t d_count = count;
241 dbus_bool_t d_traverse = traverse;
242
243 if (!message)
244 return NULL;
245
246 if (!append_accessible (message, current_object))
247 return NULL;
248 if (!append_match_rule (message, rule))
249 return NULL;
250 dbus_message_append_args (message, DBUS_TYPE_UINT32, &d_sortby,
251 DBUS_TYPE_UINT32, &d_tree,
252 DBUS_TYPE_INT32, &d_count,
253 DBUS_TYPE_BOOLEAN, &d_traverse,
254 DBUS_TYPE_INVALID);
255 reply = _atspi_dbus_send_with_reply_and_block (message, error);
256 if (!reply)
257 return NULL;
258 return return_accessibles (reply);
259 }
260
261 /**
262 * atspi_collection_get_active_descendant:
263 *
264 * Returns: (transfer full): The active descendant of the given object.
265 * Not yet implemented.
266 **/
267 AtspiAccessible *
atspi_collection_get_active_descendant(AtspiCollection * collection,GError ** error)268 atspi_collection_get_active_descendant (AtspiCollection *collection, GError **error)
269 {
270 g_warning ("AT-SPI: TODO: Implement get_active_descendants");
271 return NULL;
272 }
273
274 static void
atspi_collection_base_init(AtspiCollection * klass)275 atspi_collection_base_init (AtspiCollection *klass)
276 {
277 }
278
279 GType
atspi_collection_get_type(void)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 }
297