1
/*
2
 * AT-SPI - Assistive Technology Service Provider Interface
3
 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4
 *
5
 * Copyright 2001, 2002 Sun Microsystems Inc.,
6
 * Copyright 2001, 2002 Ximian, Inc.
7
 * Copyright 2013 SUSE LLC.
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 "atspi-private.h"
26
#include <stdlib.h> /* for malloc */
27

            
28
static GPtrArray *
29
get_object_array_and_unref (DBusMessage *reply)
30
{
31
  DBusMessageIter iter, iter_array;
32
  GPtrArray *array;
33

            
34
  if (!reply)
35
    return NULL;
36

            
37
  if (strcmp (dbus_message_get_signature (reply), "a(so)") != 0)
38
    {
39
      dbus_message_unref (reply);
40
      return NULL;
41
    }
42

            
43
  array = g_ptr_array_new ();
44

            
45
  dbus_message_iter_init (reply, &iter);
46
  dbus_message_iter_recurse (&iter, &iter_array);
47
  while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID)
48
    {
49
      AtspiAccessible *accessible = _atspi_dbus_consume_accessible (&iter_array);
50
      g_ptr_array_add (array, accessible);
51
    }
52
  dbus_message_unref (reply);
53
  return array;
54
}
55

            
56
/**
57
 * atspi_table_cell_get_column_span:
58
 * @obj: a GObject instance that implements AtspiTableCellIface
59
 *
60
 * Returns the number of columns occupied by this cell accessible.
61
 * The returned values are meaningful only if the table cell has both
62
 * STATE_VISIBLE and STATE_SHOWING.
63
 *
64
 * Returns: a gint representing the number of columns occupied by this cell,
65
 * or 0 if the cell does not implement this method.
66
 */
67
gint
68
3
atspi_table_cell_get_column_span (AtspiTableCell *obj, GError **error)
69
{
70
3
  dbus_int32_t retval = -1;
71

            
72
3
  g_return_val_if_fail (obj != NULL, -1);
73

            
74
3
  _atspi_dbus_get_property (obj, atspi_interface_table_cell, "ColumnSpan",
75
                            error, "i", &retval);
76

            
77
3
  return retval;
78
}
79

            
80
/**
81
 * atspi_table_cell_get_column_header_cells:
82
 * @obj: a GObject instance that implements AtspiTableCellIface
83
 *
84
 * Returns the column headers as an array of cell accessibles.
85
 *
86
 * Returns: (element-type AtspiAccessible) (transfer full): a GPtrArray of
87
 * AtspiAccessibles representing the column header cells.
88
 */
89
GPtrArray *
90
atspi_table_cell_get_column_header_cells (AtspiTableCell *obj, GError **error)
91
{
92
  DBusMessage *reply;
93

            
94
  g_return_val_if_fail (obj != NULL, NULL);
95

            
96
  reply = _atspi_dbus_call_partial (obj, atspi_interface_table_cell, "GetColumnHeaderCells", error, "");
97

            
98
  return get_object_array_and_unref (reply);
99
}
100

            
101
/**
102
 * atspi_table_cell_get_row_span:
103
 * @obj: a GObject instance that implements AtspiTableCellIface
104
 *
105
 * Returns the number of rows occupied by this cell accessible.
106
 * The returned values are meaningful only if the table cell has both
107
 * STATE_VISIBLE and STATE_SHOWING.
108
 *
109
 * Returns: a gint representing the number of rows occupied by this cell,
110
 * or 0 if the cell does not implement this method.
111
 */
112
gint
113
1
atspi_table_cell_get_row_span (AtspiTableCell *obj, GError **error)
114
{
115
1
  dbus_int32_t retval = -1;
116

            
117
1
  g_return_val_if_fail (obj != NULL, -1);
118

            
119
1
  _atspi_dbus_get_property (obj, atspi_interface_table_cell, "RowSpan",
120
                            error, "i", &retval);
121

            
122
1
  return retval;
123
}
124

            
125
/**
126
 * atspi_table_cell_get_row_header_cells:
127
 * @obj: a GObject instance that implements AtspiTableCellIface
128
 *
129
 * Returns the row headers as an array of cell accessibles.
130
 *
131
 * Returns: (element-type AtspiAccessible) (transfer full): a GPtrArray of
132
 * AtspiAccessibles representing the row header cells.
133
 */
134
GPtrArray *
135
atspi_table_cell_get_row_header_cells (AtspiTableCell *obj, GError **error)
136
{
137
  DBusMessage *reply;
138

            
139
  g_return_val_if_fail (obj != NULL, NULL);
140

            
141
  reply = _atspi_dbus_call_partial (obj, atspi_interface_table_cell, "GetRowHeaderCells", error, "");
142

            
143
  return get_object_array_and_unref (reply);
144
}
145

            
146
/**
147
 * atspi_table_cell_get_position:
148
 * @obj: a GObject instance that implements AtspiTableCellIface
149
 * @row: (out): the row of the given cell.
150
 * @column: (out): the column of the given cell.
151
 *
152
 * Retrieves the tabular position of this cell.
153
 *
154
 * Returns: TRUE if successful, FALSE otherwise.
155
 */
156
gint
157
1
atspi_table_cell_get_position (AtspiTableCell *obj,
158
                               gint *row,
159
                               gint *column,
160
                               GError **error)
161
{
162
  DBusMessage *reply;
163
  DBusMessageIter iter, iter_struct, iter_variant;
164
1
  dbus_int32_t d_row = -1, d_column = -1;
165
  char *iter_sig;
166

            
167
1
  g_return_val_if_fail (obj != NULL, -1);
168

            
169
1
  reply = _atspi_dbus_call_partial (obj, "org.freedesktop.DBus.Properties",
170
                                    "Get", error, "ss",
171
                                    atspi_interface_table_cell, "Position");
172

            
173
1
  if (!reply)
174
    return -1;
175

            
176
1
  dbus_message_iter_init (reply, &iter);
177

            
178
  /* TODO: Return error here */
179
1
  if (dbus_message_iter_get_arg_type (&iter) != 'v')
180
    return FALSE;
181

            
182
1
  dbus_message_iter_recurse (&iter, &iter_variant);
183
1
  iter_sig = dbus_message_iter_get_signature (&iter_variant);
184
  /* TODO: Also report error here */
185
1
  if (strcmp (iter_sig, "(ii)") != 0)
186
    {
187
      dbus_free (iter_sig);
188
      return FALSE;
189
    }
190
1
  dbus_free (iter_sig);
191

            
192
1
  dbus_message_iter_recurse (&iter_variant, &iter_struct);
193
1
  dbus_message_iter_get_basic (&iter_struct, &d_row);
194
1
  if (row)
195
1
    *row = d_row;
196
1
  dbus_message_iter_next (&iter_struct);
197
1
  dbus_message_iter_get_basic (&iter_struct, &d_column);
198
1
  if (column)
199
1
    *column = d_column;
200
1
  dbus_message_unref (reply);
201
1
  return TRUE;
202
}
203

            
204
/**
205
 * atspi_table_cell_get_row_column_span:
206
 * @obj: a GObject instance that implements AtspiTableCellIface
207
 * @row: (out): the row index of the given cell.
208
 * @column: (out): the column index of the given cell.
209
 * @row_span: (out): the number of rows occupied by this cell.
210
 * @column_span: (out): the number of columns occupied by this cell.
211
 *
212
 * Gets the row and column indexes and extents of this cell accessible.
213
 * The returned values are meaningful only if the table cell has both
214
 * STATE_VISIBLE and STATE_SHOWING.
215
 */
216
void
217
1
atspi_table_cell_get_row_column_span (AtspiTableCell *obj,
218
                                      gint *row,
219
                                      gint *column,
220
                                      gint *row_span,
221
                                      gint *column_span,
222
                                      GError **error)
223
{
224
1
  dbus_int32_t d_row = 0, d_column = 0, d_row_span = 0, d_column_span = 0;
225

            
226
1
  if (row)
227
1
    *row = -1;
228
1
  if (column)
229
1
    *column = -1;
230
1
  if (row_span)
231
1
    *row_span = -1;
232
1
  if (column_span)
233
1
    *column_span = -1;
234

            
235
1
  g_return_if_fail (obj != NULL);
236

            
237
1
  _atspi_dbus_call (obj, atspi_interface_table_cell, "GetRowColumnSpan",
238
                    error, "=>iiii", &d_row, &d_column,
239
                    &d_row_span, &d_column_span);
240

            
241
1
  if (row)
242
1
    *row = d_row;
243
1
  if (column)
244
1
    *column = d_column;
245
1
  if (row_span)
246
1
    *row_span = d_row_span;
247
1
  if (column_span)
248
1
    *column_span = d_column_span;
249
}
250

            
251
/**
252
 * atspi_table_cell_get_table:
253
 * @obj: a GObject instance that implements AtspiTableCellIface
254
 *
255
 * Returns a reference to the accessible of the containing table.
256
 *
257
 * Returns: (transfer full): the AtspiAccessible for the containing table.
258
 */
259
AtspiAccessible *
260
1
atspi_table_cell_get_table (AtspiTableCell *obj, GError **error)
261
{
262
1
  AtspiAccessible *retval = NULL;
263

            
264
1
  g_return_val_if_fail (obj != NULL, NULL);
265

            
266
1
  _atspi_dbus_get_property (obj, atspi_interface_table_cell, "Table",
267
                            error, "(so)", &retval);
268

            
269
1
  return retval;
270
}
271

            
272
static void
273
4
atspi_table_cell_base_init (AtspiTableCell *klass)
274
{
275
4
}
276

            
277
GType
278
10
atspi_table_cell_get_type (void)
279
{
280
  static GType type = 0;
281

            
282
10
  if (!type)
283
    {
284
      static const GTypeInfo tinfo = {
285
        sizeof (AtspiTableCell),
286
        (GBaseInitFunc) atspi_table_cell_base_init,
287
        (GBaseFinalizeFunc) NULL,
288
      };
289

            
290
2
      type = g_type_register_static (G_TYPE_INTERFACE, "AtspiTableCell", &tinfo, 0);
291
    }
292
10
  return type;
293
}