Allow caching of data sent with events and requesting such data
[platform/upstream/at-spi2-core.git] / atspi / atspi-component.c
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  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /*
25  *
26  * AtspiComponent function implementations
27  *
28  */
29
30 #include "atspi-private.h"
31 #include "atspi-accessible-private.h"
32
33 void
34 atspi_rect_free (AtspiRect *rect)
35 {
36   g_free (rect);
37 }
38
39 AtspiRect *
40 atspi_rect_copy (AtspiRect *src)
41 {
42   AtspiRect *dst = g_new (AtspiRect, 1);
43   dst->x = src->x;
44   dst->y = src->y;
45   dst->height = src->height;
46   dst->width = src->width;
47   return dst;
48 }
49
50 G_DEFINE_BOXED_TYPE (AtspiRect, atspi_rect, atspi_rect_copy, atspi_rect_free)
51
52 AtspiPoint *
53 atspi_point_copy (AtspiPoint *src)
54 {
55   AtspiPoint *dst = g_new (AtspiPoint, 1);
56   dst->x = src->x;
57   dst->y = src->y;
58   return dst;
59 }
60
61 G_DEFINE_BOXED_TYPE (AtspiPoint, atspi_point, atspi_point_copy, g_free)
62
63 /**
64  * atspi_component_contains:
65  * @obj: a pointer to the #AtspiComponent to query.
66  * @x: a #gint specifying the x coordinate in question.
67  * @y: a #gint specifying the y coordinate in question.
68  * @ctype: the desired coordinate system of the point (@x, @y)
69  *         (e.g. CSPI_COORD_TYPE_WINDOW, CSPI_COORD_TYPE_SCREEN).
70  *
71  * Queries whether a given #AtspiComponent contains a particular point.
72  *
73  * Returns: #TRUE if the specified component contains the point (@x, @y),
74  *          #FALSE otherwise.
75  **/
76 gboolean
77 atspi_component_contains (AtspiComponent *obj,
78                               gint x,
79                               gint y,
80                               AtspiCoordType ctype, GError **error)
81 {
82   dbus_bool_t retval = FALSE;
83   dbus_int32_t d_x = x, d_y = y;
84   dbus_uint32_t d_ctype = ctype;
85
86   g_return_val_if_fail (obj != NULL, FALSE);
87
88   _atspi_dbus_call (obj, atspi_interface_component, "Contains", error, "iiu=>b", d_x, d_y, d_ctype, &retval);
89
90   return retval;
91 }
92
93 /**
94  * atspi_component_get_accessible_at_point:
95  * @obj: a pointer to the #AtspiComponent to query.
96  * @x: a #gint specifying the x coordinate of the point in question.
97  * @y: a #gint specifying the y coordinate of the point in question.
98  * @ctype: the coordinate system of the point (@x, @y)
99  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
100  *
101  * Gets the accessible child at a given coordinate within an #AtspiComponent.
102  *
103  * Returns: (transfer full): a pointer to an #AtspiAccessible child of the
104  *          specified component which contains the point (@x, @y), or NULL if
105  *         no child contains the point.
106  **/
107 AtspiAccessible *
108 atspi_component_get_accessible_at_point (AtspiComponent *obj,
109                                           gint x,
110                                           gint y,
111                                           AtspiCoordType ctype, GError **error)
112 {
113   dbus_int32_t d_x = x, d_y = y;
114   dbus_uint32_t d_ctype = ctype;
115   DBusMessage *reply;
116
117   g_return_val_if_fail (obj != NULL, FALSE);
118
119   reply = _atspi_dbus_call_partial (obj, atspi_interface_component, "GetAccessibleAtPoint", error, "iiu", d_x, d_y, d_ctype);
120
121   return _atspi_dbus_return_accessible_from_message (reply);
122 }
123
124 /**
125  * atspi_component_get_extents:
126  * @obj: a pointer to the #AtspiComponent to query.
127  * @ctype: the desired coordinate system into which to return the results,
128  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
129  *
130  * Gets the bounding box of the specified #AtspiComponent.
131  *
132  * Returns: An #AtspiRect giving the accessible's extents.
133  **/
134 AtspiRect *
135 atspi_component_get_extents (AtspiComponent *obj,
136                                 AtspiCoordType ctype, GError **error)
137 {
138   dbus_uint32_t d_ctype = ctype;
139   AtspiRect bbox;
140   AtspiAccessible *accessible;
141
142   bbox.x = bbox.y = bbox.width = bbox.height = -1;
143   g_return_val_if_fail (obj != NULL, atspi_rect_copy (&bbox));
144
145   accessible = ATSPI_ACCESSIBLE (obj);
146   if (accessible->priv->cache && ctype == ATSPI_COORD_TYPE_SCREEN)
147   {
148     GValue *val = g_hash_table_lookup (accessible->priv->cache, "Component.ScreenExtents");
149     if (val)
150     {
151       return g_value_dup_boxed (val);
152     }
153   }
154
155   _atspi_dbus_call (obj, atspi_interface_component, "GetExtents", error, "u=>(iiii)", d_ctype, &bbox);
156   return atspi_rect_copy (&bbox);
157 }
158
159 /**
160  * atspi_component_get_position:
161  * @obj: a pointer to the #AtspiComponent to query.
162  * @ctype: the desired coordinate system into which to return the results,
163  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
164  *
165  * Gets the minimum x and y coordinates of the specified #AtspiComponent.
166  *
167  * returns: An #AtspiPoint giving the @obj's position.
168  **/
169 AtspiPoint *
170 atspi_component_get_position (AtspiComponent *obj,
171                                  AtspiCoordType ctype, GError **error)
172 {
173   dbus_int32_t d_x, d_y;
174   dbus_uint32_t d_ctype = ctype;
175   AtspiPoint ret;
176
177   ret.x = ret.y = -1;
178
179   if (!obj)
180     return atspi_point_copy (&ret);
181
182   _atspi_dbus_call (obj, atspi_interface_component, "GetPosition", error, "u=>ii", d_ctype, &d_x, &d_y);
183
184   ret.x = d_x;
185   ret.y = d_y;
186   return atspi_point_copy (&ret);
187 }
188
189 /**
190  * atspi_component_get_size:
191  * @obj: a pointer to the #AtspiComponent to query.
192  *
193  * Gets the size of the specified #AtspiComponent.
194  *
195  * returns: An #AtspiPoint giving the @obj's size.
196  **/
197 AtspiPoint *
198 atspi_component_get_size (AtspiComponent *obj, GError **error)
199 {
200   dbus_int32_t d_w, d_h;
201   AtspiPoint ret;
202
203   ret.x = ret.y = -1;
204   if (!obj)
205     return atspi_point_copy (&ret);
206
207   _atspi_dbus_call (obj, atspi_interface_component, "GetSize", error, "=>ii", &d_w, &d_h);
208   ret.x = d_w;
209   ret.y = d_h;
210   return atspi_point_copy (&ret);
211 }
212
213 /**
214  * atspi_component_get_layer:
215  * @obj: a pointer to the #AtspiComponent to query.
216  *
217  * Queries which layer the component is painted into, to help determine its 
218  *      visibility in terms of stacking order.
219  *
220  * Returns: the #AtspiComponentLayer into which this component is painted.
221  **/
222 AtspiComponentLayer
223 atspi_component_get_layer (AtspiComponent *obj, GError **error)
224 {
225   dbus_uint32_t zlayer = -1;
226
227   _atspi_dbus_call (obj, atspi_interface_component, "GetLayer", error, "=>u", &zlayer);
228
229   return zlayer;
230 }
231
232 /**
233  * atspi_component_get_mdi_z_order:
234  * @obj: a pointer to the #AtspiComponent to query.
235  *
236  * Queries the z stacking order of a component which is in the MDI or window
237  *       layer. (Bigger z-order numbers mean nearer the top)
238  *
239  * Returns: a #gshort indicating the stacking order of the component 
240  *       in the MDI layer, or -1 if the component is not in the MDI layer.
241  **/
242 gshort
243 atspi_component_get_mdi_z_order (AtspiComponent *obj, GError **error)
244 {
245   dbus_uint16_t retval = -1;
246
247   _atspi_dbus_call (obj, atspi_interface_component, "GetMDIZOrder", error, "=>n", &retval);
248
249   return retval;
250 }
251
252 /**
253  * atspi_component_grab_focus:
254  * @obj: a pointer to the #AtspiComponent on which to operate.
255  *
256  * Attempts to set the keyboard input focus to the specified
257  *         #AtspiComponent.
258  *
259  * Returns: #TRUE if successful, #FALSE otherwise.
260  *
261  **/
262 gboolean
263 atspi_component_grab_focus (AtspiComponent *obj, GError **error)
264 {
265   dbus_bool_t retval = FALSE;
266
267   _atspi_dbus_call (obj, atspi_interface_component, "GrabFocus", error, "=>b", &retval);
268
269   return retval;
270 }
271
272 /**
273  * atspi_component_get_alpha:
274  * @obj: The #AtspiComponent to be queried.
275  *
276  * Gets the opacity/alpha value of a component, if alpha blending is in use.
277  *
278  * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0. 
279  **/
280 gdouble      
281 atspi_component_get_alpha    (AtspiComponent *obj, GError **error)
282 {
283   double retval = 1;
284
285   _atspi_dbus_call (obj, atspi_interface_component, "GetAlpha", error, "=>d", &retval);
286
287   return retval;
288 }
289
290 /**
291  * atspi_component_set_extents:
292  * @obj: a pointer to the #AtspiComponent to move.
293  * @x: the new vertical position to which the component should be moved.
294  * @y: the new horizontal position to which the component should be moved.
295  * @width: the width to which the component should be resized.
296  * @height: the height to which the component should be resized.
297  * @ctype: the coordinate system in which the position is specified.
298  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
299  *
300  * Moves and resizes the specified component.
301  *
302  * Returns: #TRUE if successful; #FALSE otherwise.
303  **/
304 gboolean
305 atspi_component_set_extents (AtspiComponent *obj,
306                              gint x,
307                              gint y,
308                              gint width,
309                              gint height,
310                              AtspiCoordType ctype,
311                              GError **error)
312 {
313   dbus_int32_t d_x = x, d_y = y, d_width = width, d_height = height;
314   dbus_uint32_t d_ctype = ctype;
315   DBusMessageIter iter, iter_struct;
316   DBusMessage *message, *reply;
317   dbus_bool_t retval = FALSE;
318   AtspiAccessible *aobj = ATSPI_ACCESSIBLE (obj);
319
320   g_return_val_if_fail (obj != NULL, FALSE);
321
322   if (!aobj->parent.app || !aobj->parent.app->bus_name)
323   {
324     g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_APPLICATION_GONE,
325                           _("The application no longer exists"));
326     return FALSE;
327   }
328
329   message = dbus_message_new_method_call (aobj->parent.app->bus_name,
330                                           aobj->parent.path,
331                                           atspi_interface_component,
332                                           "SetExtents");
333   if (!message)
334     return FALSE;
335
336   dbus_message_iter_init_append (message, &iter);
337   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL, &iter_struct))
338   {
339     dbus_message_unref (message);
340     return FALSE;
341   }
342   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_x);
343   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_y);
344   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_width);
345   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_height);
346   dbus_message_iter_close_container (&iter, &iter_struct);
347   dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &d_ctype);
348
349   reply = _atspi_dbus_send_with_reply_and_block (message, error);
350   dbus_message_get_args (reply, NULL, DBUS_TYPE_BOOLEAN, &retval,
351                               DBUS_TYPE_INVALID);
352   dbus_message_unref (reply);
353   return retval;
354 }
355
356 /**
357  * atspi_component_set_position:
358  * @obj: a pointer to the #AtspiComponent to move.
359  * @x: the new vertical position to which the component should be moved.
360  * @y: the new horizontal position to which the component should be moved.
361  * @ctype: the coordinate system in which the position is specified.
362  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
363  *
364  * Returns: #TRUE if successful; #FALSE otherwise.
365  *
366  * Moves the component to the specified position.
367  **/
368 gboolean
369 atspi_component_set_position (AtspiComponent *obj,
370                               gint x,
371                               gint y,
372                               AtspiCoordType ctype,
373                               GError **error)
374 {
375   dbus_int32_t d_x = x, d_y = y;
376   dbus_uint32_t d_ctype = ctype;
377   dbus_bool_t ret = FALSE;
378
379   g_return_val_if_fail (obj != NULL, FALSE);
380
381   _atspi_dbus_call (obj, atspi_interface_component, "SetPosition", error,
382                     "iiu=>b", d_x, d_y, d_ctype, &ret);
383
384   return ret;
385 }
386
387 /**
388  * atspi_component_set_size:
389  * @obj: a pointer to the #AtspiComponent to query.
390  * @width: the width to which the component should be resized.
391  * @height: the height to which the component should be resized.
392  *
393  * Returns: #TRUE if successful; #FALSE otherwise.
394  *
395  * Resizes the specified component to the given coordinates.
396  **/
397 gboolean
398 atspi_component_set_size (AtspiComponent *obj,
399                           gint width,
400                           gint height,
401                           GError **error)
402 {
403   dbus_int32_t d_width = width, d_height = height;
404   dbus_bool_t ret = FALSE;
405
406   g_return_val_if_fail (obj != NULL, FALSE);
407
408   _atspi_dbus_call (obj, atspi_interface_component, "SetSize", error, "ii=>b",
409                     d_width, d_height, &ret);
410
411   return ret;
412 }
413
414 static void
415 atspi_component_base_init (AtspiComponent *klass)
416 {
417 }
418
419 GType
420 atspi_component_get_type (void)
421 {
422   static GType type = 0;
423
424   if (!type) {
425     static const GTypeInfo tinfo =
426     {
427       sizeof (AtspiComponent),
428       (GBaseInitFunc) atspi_component_base_init,
429       (GBaseFinalizeFunc) NULL,
430     };
431
432     type = g_type_register_static (G_TYPE_INTERFACE, "AtspiComponent", &tinfo, 0);
433
434   }
435   return type;
436 }