Add simple nActions property, getDescription, getName, getKeyBinding
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / action.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 AtkAction *
28 get_action (DBusMessage * message)
29 {
30   AtkObject *obj = spi_dbus_get_object (dbus_message_get_path (message));
31   if (!obj)
32     return NULL;
33   return ATK_ACTION (obj);
34 }
35
36 static AtkAction *
37 get_action_from_path (const char *path, void *user_data)
38 {
39   AtkObject *obj = spi_dbus_get_object (path);
40   if (!obj || !ATK_IS_ACTION(obj))
41     return NULL;
42   return ATK_ACTION (obj);
43 }
44
45 static dbus_bool_t
46 impl_get_nActions (const char *path, DBusMessageIter *iter, void *user_data)
47 {
48   AtkAction *action = get_action_from_path (path, user_data);
49   if (!action)
50     return FALSE;
51   return droute_return_v_int32 (iter, atk_action_get_n_actions (action));
52 }
53
54 static DBusMessage *
55 impl_get_description (DBusConnection *bus, DBusMessage *message, void *user_data)
56 {
57   DBusMessage *reply;
58   dbus_int32_t index;
59   const char *desc;
60   AtkAction *action = get_action (message);
61
62   if (!action) return spi_dbus_general_error (message);
63   if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
64   {
65     return spi_dbus_general_error (message);
66   }
67   desc = atk_action_get_description(action, index);
68   if (!desc) desc = "";
69   reply = dbus_message_new_method_return (message);
70   if (reply)
71   {
72     dbus_message_append_args (reply, DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID);
73   }
74   return reply;
75 }
76
77 static DBusMessage *
78 impl_get_name (DBusConnection *bus, DBusMessage *message, void *user_data)
79 {
80   DBusMessage *reply;
81   dbus_int32_t index;
82   const char *name;
83   AtkAction *action = get_action (message);
84
85   if (!action) return spi_dbus_general_error (message);
86   if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
87   {
88     return spi_dbus_general_error (message);
89   }
90   name = atk_action_get_name(action, index);
91   if (!name) name = "";
92   reply = dbus_message_new_method_return (message);
93   if (reply)
94   {
95     dbus_message_append_args (reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
96   }
97   return reply;
98 }
99
100 static DBusMessage *
101 impl_get_keybinding (DBusConnection *bus, DBusMessage *message, void *user_data)
102 {
103   DBusMessage *reply;
104   dbus_int32_t index;
105   const char *kb;
106   AtkAction *action = get_action (message);
107
108   if (!action) return spi_dbus_general_error (message);
109   if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
110   {
111     return spi_dbus_general_error (message);
112   }
113   kb = atk_action_get_keybinding(action, index);
114   if (!kb) kb = "";
115   reply = dbus_message_new_method_return (message);
116   if (reply)
117   {
118     dbus_message_append_args (reply, DBUS_TYPE_STRING, &kb, DBUS_TYPE_INVALID);
119   }
120   return reply;
121 }
122
123 static DBusMessage *impl_getActions(DBusConnection *bus, DBusMessage *message, void *user_data)
124 {
125   AtkAction *action = get_action(message);
126   DBusMessage *reply;
127   gint count;
128   gint i;
129   DBusMessageIter iter, iter_array, iter_struct;
130
131   if (!action)
132     return spi_dbus_general_error (message);
133   count = atk_action_get_n_actions(action);
134   reply = dbus_message_new_method_return (message);
135   if (!reply) goto oom;
136   dbus_message_iter_init_append (reply, &iter);
137   if (!dbus_message_iter_open_container
138       (&iter, DBUS_TYPE_ARRAY, "(sss)", &iter_array))
139     goto oom;
140   for (i = 0; i < count; i++)
141     {
142       const char *name = atk_action_get_name(action, i);
143       const char *desc = atk_action_get_description(action, i);
144       const char *kb = atk_action_get_keybinding(action, i);
145       if (!name) name = "";
146       if (!desc) desc = "";
147       if (!kb) kb = "";
148       if (!dbus_message_iter_open_container(&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct)) goto oom;
149       dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &name);
150       dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &desc);
151       dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &kb);
152       if (!dbus_message_iter_close_container(&iter_array, &iter_struct)) goto oom;
153     }
154   if (!dbus_message_iter_close_container (&iter, &iter_array))
155     goto oom;
156   return reply;
157 oom:
158   // TODO: handle out-of-memory
159   return reply;
160 }
161
162 static DBusMessage *impl_doAction(DBusConnection *bus, DBusMessage *message, void *user_data)
163 {
164   AtkAction *action = get_action(message);
165   DBusError error;
166   dbus_int32_t index;
167   dbus_bool_t rv;
168   DBusMessage *reply;
169
170   if (!action)
171     return spi_dbus_general_error (message);
172   dbus_error_init (&error);
173   if (!dbus_message_get_args
174       (message, &error, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
175     {
176       return SPI_DBUS_RETURN_ERROR (message, &error);
177     }
178   rv = atk_action_do_action(action, index);
179   reply = dbus_message_new_method_return (message);
180   if (reply)
181     {
182       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv, DBUS_TYPE_INVALID);
183     }
184   return reply;
185 }
186
187 DRouteMethod methods[] =
188 {
189   { impl_get_description, "getDescription" },
190   { impl_get_name, "getName" },
191   { impl_get_keybinding, "getKeyBinding" },
192   {impl_getActions, "getActions"},
193   {impl_doAction, "doAction"},
194   {NULL, NULL }
195 };
196
197 static DRouteProperty properties[] =
198 {
199   { impl_get_nActions, NULL, "nActions" },
200   { NULL, NULL }
201 };
202
203 void
204 spi_initialize_action (DRouteData * data)
205 {
206   droute_add_interface (data, SPI_DBUS_INTERFACE_ACTION,
207                         methods, properties,
208                         (DRouteGetDatumFunction) get_action_from_path,
209                         NULL);
210 };