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 Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 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
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the
21
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22
 * Boston, MA 02110-1301, USA.
23
 */
24

            
25
#include "bridge.h"
26
#include <atk/atk.h>
27
#include <droute/droute.h>
28

            
29
#include "spi-dbus.h"
30

            
31
#include "introspection.h"
32

            
33
static dbus_bool_t
34
1
impl_get_NActions (DBusMessageIter *iter, void *user_data)
35
{
36
1
  AtkAction *action = (AtkAction *) user_data;
37

            
38
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data), FALSE);
39
1
  return droute_return_v_int32 (iter, atk_action_get_n_actions (action));
40
}
41

            
42
static DBusMessage *
43
1
impl_get_description (DBusConnection *bus, DBusMessage *message, void *user_data)
44
{
45
1
  AtkAction *action = (AtkAction *) user_data;
46
  DBusMessage *reply;
47
  dbus_int32_t index;
48
  const char *desc;
49

            
50
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
51
                        droute_not_yet_handled_error (message));
52
1
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
53
    {
54
      return droute_invalid_arguments_error (message);
55
    }
56
1
  desc = atk_action_get_description (action, index);
57
1
  if (!desc)
58
    desc = "";
59
1
  reply = dbus_message_new_method_return (message);
60
1
  if (reply)
61
    {
62
1
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &desc,
63
                                DBUS_TYPE_INVALID);
64
    }
65
1
  return reply;
66
}
67

            
68
static DBusMessage *
69
1
impl_get_name (DBusConnection *bus, DBusMessage *message, void *user_data)
70
{
71
  DBusMessage *reply;
72
  dbus_int32_t index;
73
  const char *name;
74
1
  AtkAction *action = (AtkAction *) user_data;
75

            
76
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
77
                        droute_not_yet_handled_error (message));
78
1
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
79
    {
80
      return droute_invalid_arguments_error (message);
81
    }
82
1
  name = atk_action_get_name (action, index);
83
1
  if (!name)
84
    name = "";
85
1
  reply = dbus_message_new_method_return (message);
86
1
  if (reply)
87
    {
88
1
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &name,
89
                                DBUS_TYPE_INVALID);
90
    }
91
1
  return reply;
92
}
93

            
94
static DBusMessage *
95
1
impl_get_localized_name (DBusConnection *bus, DBusMessage *message, void *user_data)
96
{
97
  DBusMessage *reply;
98
  dbus_int32_t index;
99
  const char *name;
100
1
  AtkAction *action = (AtkAction *) user_data;
101

            
102
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
103
                        droute_not_yet_handled_error (message));
104
1
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
105
    {
106
      return droute_invalid_arguments_error (message);
107
    }
108
1
  name = atk_action_get_localized_name (action, index);
109
1
  if (!name)
110
    name = "";
111
1
  reply = dbus_message_new_method_return (message);
112
1
  if (reply)
113
    {
114
1
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &name,
115
                                DBUS_TYPE_INVALID);
116
    }
117
1
  return reply;
118
}
119

            
120
static DBusMessage *
121
1
impl_get_keybinding (DBusConnection *bus, DBusMessage *message, void *user_data)
122
{
123
  DBusMessage *reply;
124
  dbus_int32_t index;
125
  const char *kb;
126
1
  AtkAction *action = (AtkAction *) user_data;
127

            
128
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
129
                        droute_not_yet_handled_error (message));
130
1
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
131
    {
132
      return droute_invalid_arguments_error (message);
133
    }
134
1
  kb = atk_action_get_keybinding (action, index);
135
1
  if (!kb)
136
    kb = "";
137
1
  reply = dbus_message_new_method_return (message);
138
1
  if (reply)
139
    {
140
1
      dbus_message_append_args (reply, DBUS_TYPE_STRING, &kb,
141
                                DBUS_TYPE_INVALID);
142
    }
143
1
  return reply;
144
}
145

            
146
static DBusMessage *
147
impl_GetActions (DBusConnection *bus, DBusMessage *message, void *user_data)
148
{
149
  AtkAction *action = (AtkAction *) user_data;
150
  DBusMessage *reply;
151
  gint count;
152
  gint i;
153
  DBusMessageIter iter, iter_array, iter_struct;
154

            
155
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
156
                        droute_not_yet_handled_error (message));
157
  count = atk_action_get_n_actions (action);
158
  reply = dbus_message_new_method_return (message);
159
  if (!reply)
160
    goto oom;
161
  dbus_message_iter_init_append (reply, &iter);
162
  if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(sss)", &iter_array))
163
    goto oom;
164
  for (i = 0; i < count; i++)
165
    {
166
      const char *lname = atk_action_get_localized_name (action, i);
167
      const char *desc = atk_action_get_description (action, i);
168
      const char *kb = atk_action_get_keybinding (action, i);
169
      if (!lname)
170
        lname = "";
171
      if (!desc)
172
        desc = "";
173
      if (!kb)
174
        kb = "";
175
      if (!dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct))
176
        goto oom;
177
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &lname);
178
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &desc);
179
      dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &kb);
180
      if (!dbus_message_iter_close_container (&iter_array, &iter_struct))
181
        goto oom;
182
    }
183
  if (!dbus_message_iter_close_container (&iter, &iter_array))
184
    goto oom;
185
  return reply;
186
oom:
187
  // TODO: handle out-of-memory
188
  return reply;
189
}
190

            
191
static DBusMessage *
192
1
impl_DoAction (DBusConnection *bus, DBusMessage *message, void *user_data)
193
{
194
1
  AtkAction *action = (AtkAction *) user_data;
195
  dbus_int32_t index;
196
1
  dbus_bool_t rv = TRUE;
197
  DBusMessage *reply;
198

            
199
1
  g_return_val_if_fail (ATK_IS_ACTION (user_data),
200
                        droute_not_yet_handled_error (message));
201
1
  if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID))
202
    {
203
      return droute_invalid_arguments_error (message);
204
    }
205
1
  reply = dbus_message_new_method_return (message);
206
1
  if (reply)
207
    {
208
1
      dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
209
                                DBUS_TYPE_INVALID);
210
    }
211
1
  dbus_connection_send (bus, reply, NULL);
212
1
  dbus_message_unref (reply);
213
1
  atk_action_do_action (action, index);
214
1
  return NULL;
215
}
216

            
217
DRouteMethod methods[] = {
218
  { impl_get_description, "GetDescription" },
219
  { impl_get_name, "GetName" },
220
  { impl_get_localized_name, "GetLocalizedName" },
221
  { impl_get_keybinding, "GetKeyBinding" },
222
  { impl_GetActions, "GetActions" },
223
  { impl_DoAction, "DoAction" },
224
  { NULL, NULL }
225
};
226

            
227
static DRouteProperty properties[] = {
228
  { impl_get_NActions, NULL, "NActions" },
229
  { NULL, NULL }
230
};
231

            
232
void
233
161
spi_initialize_action (DRoutePath *path)
234
{
235
161
  spi_atk_add_interface (path,
236
                         ATSPI_DBUS_INTERFACE_ACTION,
237
                         spi_org_a11y_atspi_Action, methods, properties);
238
161
};