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