2.34.0
[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 Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 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  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, 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: (nullable) (transfer full): a pointer to an
104  *          #AtspiAccessible child of the specified component which
105  *          contains the point (@x, @y), or NULL if no child contains
106  *          the point.
107  **/
108 AtspiAccessible *
109 atspi_component_get_accessible_at_point (AtspiComponent *obj,
110                                           gint x,
111                                           gint y,
112                                           AtspiCoordType ctype, GError **error)
113 {
114   dbus_int32_t d_x = x, d_y = y;
115   dbus_uint32_t d_ctype = ctype;
116   DBusMessage *reply;
117
118   g_return_val_if_fail (obj != NULL, FALSE);
119
120   reply = _atspi_dbus_call_partial (obj, atspi_interface_component, "GetAccessibleAtPoint", error, "iiu", d_x, d_y, d_ctype);
121
122   return _atspi_dbus_return_accessible_from_message (reply);
123 }
124
125 /**
126  * atspi_component_get_extents:
127  * @obj: a pointer to the #AtspiComponent to query.
128  * @ctype: the desired coordinate system into which to return the results,
129  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
130  *
131  * Gets the bounding box of the specified #AtspiComponent.
132  * The returned values are meaningful only if the Component has both
133  * STATE_VISIBLE and STATE_SHOWING.
134  *
135  * Returns: An #AtspiRect giving the accessible's extents.
136  **/
137 AtspiRect *
138 atspi_component_get_extents (AtspiComponent *obj,
139                                 AtspiCoordType ctype, GError **error)
140 {
141   dbus_uint32_t d_ctype = ctype;
142   AtspiRect bbox;
143   AtspiAccessible *accessible;
144
145   bbox.x = bbox.y = bbox.width = bbox.height = -1;
146   g_return_val_if_fail (obj != NULL, atspi_rect_copy (&bbox));
147
148   accessible = ATSPI_ACCESSIBLE (obj);
149   if (accessible->priv->cache && ctype == ATSPI_COORD_TYPE_SCREEN)
150   {
151     GValue *val = g_hash_table_lookup (accessible->priv->cache, "Component.ScreenExtents");
152     if (val)
153     {
154       return g_value_dup_boxed (val);
155     }
156   }
157
158   _atspi_dbus_call (obj, atspi_interface_component, "GetExtents", error, "u=>(iiii)", d_ctype, &bbox);
159   return atspi_rect_copy (&bbox);
160 }
161
162 /**
163  * atspi_component_get_position:
164  * @obj: a pointer to the #AtspiComponent to query.
165  * @ctype: the desired coordinate system into which to return the results,
166  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
167  *
168  * Gets the minimum x and y coordinates of the specified #AtspiComponent.
169  * The returned values are meaningful only if the Component has both
170  * STATE_VISIBLE and STATE_SHOWING.
171  *
172  * returns: An #AtspiPoint giving the @obj's position.
173  **/
174 AtspiPoint *
175 atspi_component_get_position (AtspiComponent *obj,
176                                  AtspiCoordType ctype, GError **error)
177 {
178   dbus_int32_t d_x, d_y;
179   dbus_uint32_t d_ctype = ctype;
180   AtspiPoint ret;
181
182   ret.x = ret.y = -1;
183
184   if (!obj)
185     return atspi_point_copy (&ret);
186
187   _atspi_dbus_call (obj, atspi_interface_component, "GetPosition", error, "u=>ii", d_ctype, &d_x, &d_y);
188
189   ret.x = d_x;
190   ret.y = d_y;
191   return atspi_point_copy (&ret);
192 }
193
194 /**
195  * atspi_component_get_size:
196  * @obj: a pointer to the #AtspiComponent to query.
197  *
198  * Gets the size of the specified #AtspiComponent.
199  * The returned values are meaningful only if the Component has both
200  * STATE_VISIBLE and STATE_SHOWING.
201  *
202  * returns: An #AtspiPoint giving the @obj's size.
203  **/
204 AtspiPoint *
205 atspi_component_get_size (AtspiComponent *obj, GError **error)
206 {
207   dbus_int32_t d_w, d_h;
208   AtspiPoint ret;
209
210   ret.x = ret.y = -1;
211   if (!obj)
212     return atspi_point_copy (&ret);
213
214   _atspi_dbus_call (obj, atspi_interface_component, "GetSize", error, "=>ii", &d_w, &d_h);
215   ret.x = d_w;
216   ret.y = d_h;
217   return atspi_point_copy (&ret);
218 }
219
220 /**
221  * atspi_component_get_layer:
222  * @obj: a pointer to the #AtspiComponent to query.
223  *
224  * Queries which layer the component is painted into, to help determine its 
225  *      visibility in terms of stacking order.
226  *
227  * Returns: the #AtspiComponentLayer into which this component is painted.
228  **/
229 AtspiComponentLayer
230 atspi_component_get_layer (AtspiComponent *obj, GError **error)
231 {
232   dbus_uint32_t zlayer = -1;
233
234   _atspi_dbus_call (obj, atspi_interface_component, "GetLayer", error, "=>u", &zlayer);
235
236   return zlayer;
237 }
238
239 /**
240  * atspi_component_get_mdi_z_order:
241  * @obj: a pointer to the #AtspiComponent to query.
242  *
243  * Queries the z stacking order of a component which is in the MDI or window
244  *       layer. (Bigger z-order numbers mean nearer the top)
245  *
246  * Returns: a #gshort indicating the stacking order of the component 
247  *       in the MDI layer, or -1 if the component is not in the MDI layer.
248  **/
249 gshort
250 atspi_component_get_mdi_z_order (AtspiComponent *obj, GError **error)
251 {
252   dbus_uint16_t retval = -1;
253
254   _atspi_dbus_call (obj, atspi_interface_component, "GetMDIZOrder", error, "=>n", &retval);
255
256   return retval;
257 }
258
259 /**
260  * atspi_component_grab_focus:
261  * @obj: a pointer to the #AtspiComponent on which to operate.
262  *
263  * Attempts to set the keyboard input focus to the specified
264  *         #AtspiComponent.
265  *
266  * Returns: #TRUE if successful, #FALSE otherwise.
267  *
268  **/
269 gboolean
270 atspi_component_grab_focus (AtspiComponent *obj, GError **error)
271 {
272   dbus_bool_t retval = FALSE;
273
274   _atspi_dbus_call (obj, atspi_interface_component, "GrabFocus", error, "=>b", &retval);
275
276   return retval;
277 }
278
279 /**
280  * atspi_component_get_alpha:
281  * @obj: The #AtspiComponent to be queried.
282  *
283  * Gets the opacity/alpha value of a component, if alpha blending is in use.
284  *
285  * Returns: the opacity value of a component, as a #gdouble between 0.0 and 1.0. 
286  **/
287 gdouble      
288 atspi_component_get_alpha    (AtspiComponent *obj, GError **error)
289 {
290   double retval = 1;
291
292   _atspi_dbus_call (obj, atspi_interface_component, "GetAlpha", error, "=>d", &retval);
293
294   return retval;
295 }
296
297 /**
298  * atspi_component_set_extents:
299  * @obj: a pointer to the #AtspiComponent to move.
300  * @x: the new vertical position to which the component should be moved.
301  * @y: the new horizontal position to which the component should be moved.
302  * @width: the width to which the component should be resized.
303  * @height: the height to which the component should be resized.
304  * @ctype: the coordinate system in which the position is specified.
305  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
306  *
307  * Moves and resizes the specified component.
308  *
309  * Returns: #TRUE if successful; #FALSE otherwise.
310  **/
311 gboolean
312 atspi_component_set_extents (AtspiComponent *obj,
313                              gint x,
314                              gint y,
315                              gint width,
316                              gint height,
317                              AtspiCoordType ctype,
318                              GError **error)
319 {
320   dbus_int32_t d_x = x, d_y = y, d_width = width, d_height = height;
321   dbus_uint32_t d_ctype = ctype;
322   DBusMessageIter iter, iter_struct;
323   DBusMessage *message, *reply;
324   dbus_bool_t retval = FALSE;
325   AtspiAccessible *aobj = ATSPI_ACCESSIBLE (obj);
326
327   g_return_val_if_fail (obj != NULL, FALSE);
328
329   if (!aobj->parent.app || !aobj->parent.app->bus_name)
330   {
331     g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_APPLICATION_GONE,
332                           _("The application no longer exists"));
333     return FALSE;
334   }
335
336   message = dbus_message_new_method_call (aobj->parent.app->bus_name,
337                                           aobj->parent.path,
338                                           atspi_interface_component,
339                                           "SetExtents");
340   if (!message)
341     return FALSE;
342
343   dbus_message_iter_init_append (message, &iter);
344   if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL, &iter_struct))
345   {
346     dbus_message_unref (message);
347     return FALSE;
348   }
349   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_x);
350   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_y);
351   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_width);
352   dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &d_height);
353   dbus_message_iter_close_container (&iter, &iter_struct);
354   dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &d_ctype);
355
356   reply = _atspi_dbus_send_with_reply_and_block (message, error);
357   dbus_message_get_args (reply, NULL, DBUS_TYPE_BOOLEAN, &retval,
358                               DBUS_TYPE_INVALID);
359   dbus_message_unref (reply);
360   return retval;
361 }
362
363 /**
364  * atspi_component_set_position:
365  * @obj: a pointer to the #AtspiComponent to move.
366  * @x: the new vertical position to which the component should be moved.
367  * @y: the new horizontal position to which the component should be moved.
368  * @ctype: the coordinate system in which the position is specified.
369  *         (e.g. ATSPI_COORD_TYPE_WINDOW, ATSPI_COORD_TYPE_SCREEN).
370  *
371  * Moves the component to the specified position.
372  *
373  * Returns: #TRUE if successful; #FALSE otherwise.
374  **/
375 gboolean
376 atspi_component_set_position (AtspiComponent *obj,
377                               gint x,
378                               gint y,
379                               AtspiCoordType ctype,
380                               GError **error)
381 {
382   dbus_int32_t d_x = x, d_y = y;
383   dbus_uint32_t d_ctype = ctype;
384   dbus_bool_t ret = FALSE;
385
386   g_return_val_if_fail (obj != NULL, FALSE);
387
388   _atspi_dbus_call (obj, atspi_interface_component, "SetPosition", error,
389                     "iiu=>b", d_x, d_y, d_ctype, &ret);
390
391   return ret;
392 }
393
394 /**
395  * atspi_component_set_size:
396  * @obj: a pointer to the #AtspiComponent to query.
397  * @width: the width to which the component should be resized.
398  * @height: the height to which the component should be resized.
399  *
400  * Resizes the specified component to the given coordinates.
401  *
402  * Returns: #TRUE if successful; #FALSE otherwise.
403  **/
404 gboolean
405 atspi_component_set_size (AtspiComponent *obj,
406                           gint width,
407                           gint height,
408                           GError **error)
409 {
410   dbus_int32_t d_width = width, d_height = height;
411   dbus_bool_t ret = FALSE;
412
413   g_return_val_if_fail (obj != NULL, FALSE);
414
415   _atspi_dbus_call (obj, atspi_interface_component, "SetSize", error, "ii=>b",
416                     d_width, d_height, &ret);
417
418   return ret;
419 }
420
421 /**
422  * atspi_component_scroll_to:
423  * @obj: a pointer to the #AtspiComponent object on which to operate.
424  * @type: a #AtspiScrollType indicating where the object should be placed on the
425  *        screen.
426  *
427  * Scrolls whatever container of the #AtspiComponent object so it becomes
428  * visible on the screen.
429  *
430  * Returns: #TRUE if successful, #FALSE otherwise.
431  **/
432 gboolean
433 atspi_component_scroll_to (AtspiComponent *obj,
434                            AtspiScrollType type,
435                            GError **error)
436 {
437   dbus_bool_t retval = FALSE;
438
439   g_return_val_if_fail (obj != NULL, FALSE);
440
441   _atspi_dbus_call (obj, atspi_interface_component,
442                     "ScrollTo", error, "u=>b", type, &retval);
443
444   return retval;
445 }
446
447 /**
448  * atspi_component_scroll_to_point:
449  * @obj: a pointer to the #AtspiComponent object on which to operate.
450  * @coords: a #AtspiCoordType indicating whether the coordinates are relative to
451  *          the screen, to the window, or to the parent object.
452  * @x: the x coordinate of the point to reach
453  * @y: the y coordinate of the point to reach
454  * @error: return location for a #GError
455  *
456  * Scrolls whatever container of the #AtspiComponent object so it becomes
457  * visible on the screen at a given position.
458  *
459  * Returns: #TRUE if successful, #FALSE otherwise.
460  **/
461 gboolean
462 atspi_component_scroll_to_point (AtspiComponent *obj,
463                                  AtspiCoordType coords,
464                                  gint x,
465                                  gint y,
466                                  GError **error)
467 {
468   dbus_bool_t retval = FALSE;
469
470   g_return_val_if_fail (obj != NULL, FALSE);
471
472   _atspi_dbus_call (obj, atspi_interface_component,
473                     "ScrollToPoint", error, "uii=>b", coords, x, y, &retval);
474
475   return retval;
476 }
477
478 static void
479 atspi_component_base_init (AtspiComponent *klass)
480 {
481 }
482
483 GType
484 atspi_component_get_type (void)
485 {
486   static GType type = 0;
487
488   if (!type) {
489     static const GTypeInfo tinfo =
490     {
491       sizeof (AtspiComponent),
492       (GBaseInitFunc) atspi_component_base_init,
493       (GBaseFinalizeFunc) NULL,
494     };
495
496     type = g_type_register_static (G_TYPE_INTERFACE, "AtspiComponent", &tinfo, 0);
497
498   }
499   return type;
500 }