Change interface name to org.freedesktop.atspi.Tree
[platform/core/uifw/at-spi2-atk.git] / libspi / tree.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 #define get_object(message) spi_dbus_get_object(dbus_message_get_path(message))
28
29 static dbus_bool_t
30 spi_dbus_append_tree_helper (DBusMessageIter * iter_array, AtkObject * obj,
31                              DRouteData * data)
32 {
33   DBusMessageIter iter_struct, iter_sub_array;
34   char *path = NULL;
35   char *path_parent;
36   const char *name, *desc;
37   dbus_uint16_t updating = 1;
38   int i;
39   dbus_uint32_t role;
40
41   gint childcount;
42   GSList *l;
43
44   dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL,
45                                     &iter_struct);
46   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT16, &updating);
47   path = spi_dbus_get_path (obj);
48   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
49   path_parent = spi_dbus_get_path (atk_object_get_parent(obj));
50   if (!path_parent) path_parent = g_strdup("/");
51   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path_parent);
52   g_free(path_parent);
53   dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "o",
54                                     &iter_sub_array);
55   childcount = atk_object_get_n_accessible_children (obj);
56   for (i = 0; i < childcount; i++)
57     {
58       AtkObject *child = atk_object_ref_accessible_child (obj, i);
59       char *child_path = spi_dbus_get_path (child);
60       if (child_path)
61         {
62           dbus_message_iter_append_basic (&iter_sub_array,
63                                           DBUS_TYPE_OBJECT_PATH, &child_path);
64           g_free (child_path);
65         }
66       if (child)
67         g_object_unref (child);
68     }
69   if (!dbus_message_iter_close_container (&iter_struct, &iter_sub_array))
70     goto oom;
71   dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s",
72                                     &iter_sub_array);
73   for (l = data->interfaces; l; l = g_slist_next (l))
74     {
75       DRouteInterface *iface_def = (DRouteInterface *) l->data;
76       void *datum = NULL;
77       if (iface_def->get_datum)
78         {
79           datum = (*iface_def->get_datum) (path, data->user_data);
80           if (!datum)
81             continue;
82         }
83       dbus_message_iter_append_basic (&iter_sub_array, DBUS_TYPE_STRING,
84                                       &iface_def->name);
85       if (iface_def->free_datum)
86         (*iface_def->free_datum) (datum);
87     }
88   if (!dbus_message_iter_close_container (&iter_struct, &iter_sub_array))
89     goto oom;
90   name = atk_object_get_name (obj);
91   if (!name)
92     name = "";
93   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
94   role = spi_accessible_role_from_atk_role (atk_object_get_role (obj));
95   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_UINT32, &role);
96   desc = atk_object_get_description (obj);
97   if (!desc)
98     desc = "";
99   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
100   if (!dbus_message_iter_close_container (iter_array, &iter_struct))
101     goto oom;
102   for (i = 0; i < childcount; i++)
103     {
104       AtkObject *child = atk_object_ref_accessible_child (obj, i);
105       dbus_bool_t result;
106       if (!child)
107         continue;
108       result = spi_dbus_append_tree_helper (iter_array, child, data);
109       g_object_unref (child);
110       if (!result)
111         goto oom;
112     }
113   g_free (path);
114   return TRUE;
115 oom:
116   if (path) g_free(path);
117   return FALSE;
118 }
119
120 dbus_bool_t
121 spi_dbus_append_tree (DBusMessage * message, AtkObject * obj,
122                       DRouteData * data)
123 {
124   DBusMessageIter iter, iter_array;
125   dbus_bool_t result;
126
127   dbus_message_iter_init_append (message, &iter);
128   dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(qooaoassus)",
129                                     &iter_array);
130   result = spi_dbus_append_tree_helper (&iter_array, obj, data);
131   if (result)
132     result = dbus_message_iter_close_container (&iter, &iter_array);
133   return result;
134 }
135
136 static DBusMessage *
137 impl_getRoot (DBusConnection * bus, DBusMessage * message, void *user_data)
138 {
139   AtkObject *root = atk_get_root();
140   char *path;
141   DBusMessage *reply;
142
143   if (root) path = spi_dbus_get_path(root);
144   if (!root || !path)
145     return spi_dbus_general_error (message);
146   reply = dbus_message_new_method_return (message);
147   dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path,
148                             DBUS_TYPE_INVALID);
149   g_free (path);
150   return reply;
151 }
152
153 static DBusMessage *
154 impl_getTree (DBusConnection * bus, DBusMessage * message, void *user_data)
155 {
156   DBusMessage *reply;
157   AtkObject *root = atk_get_root();
158
159   if (!root) return spi_dbus_general_error(message);
160   reply = dbus_message_new_method_return (message);
161   spi_dbus_append_tree (reply, root, (DRouteData *) user_data);
162   return reply;
163 }
164
165 static DRouteMethod methods[] = {
166   {DROUTE_METHOD, impl_getRoot, "getRoot", "o,root,o" },
167   {DROUTE_METHOD, impl_getTree, "getTree", "a(qooaoassus),tree,o", TRUE},
168   {0, NULL, NULL, NULL}
169 };
170
171 void
172 spi_initialize_tree (DRouteData * data)
173 {
174   droute_add_interface (data, "org.freedesktop.atspi.Tree",
175                         methods, NULL, NULL, NULL);
176 };