Fix gtk-doc for AtspiRegistry.
[platform/upstream/at-spi2-core.git] / atspi / atspi-registry.c
1
2 /*
3  * AT-SPI - Assistive Technology Service Provider Interface
4  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5  *
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 /* atspi_registry.c: Global functions wrapping the registry */
26
27 #include "atspi-private.h"
28
29 /**
30  * atspi_get_desktop_count:
31  *
32  * Gets the number of virtual desktops.
33  * NOTE: multiple virtual desktops are not implemented yet; as a 
34  * consequence, this function always returns 1.
35  *
36  * Returns: a #gint indicating the number of active virtual desktops.
37  **/
38 gint
39 atspi_get_desktop_count ()
40 {
41   return 1;
42 }
43
44 /**
45  * atspi_get_desktop:
46  * @i: a #gint indicating which of the accessible desktops is to be returned.
47  *
48  * Gets the virtual desktop indicated by index @i.
49  * NOTE: currently multiple virtual desktops are not implemented;
50  * as a consequence, any @i value different from 0 will not return a
51  * virtual desktop - instead it will return NULL.
52  *
53  * Returns: (transfer full): a pointer to the @i-th virtual desktop's
54  * #AtspiAccessible representation.
55  **/
56 AtspiAccessible*
57 atspi_get_desktop (gint i)
58 {
59   if (i != 0) return NULL;
60   return _atspi_ref_accessible (atspi_bus_registry, atspi_path_root);
61 }
62
63 /**
64  * atspi_get_desktop_list:
65  *
66  * Gets the list of virtual desktops.  On return, @list will point
67  *     to a newly-created, NULL terminated array of virtual desktop
68  *     pointers.
69  *     It is the responsibility of the caller to free this array when
70  *     it is no longer needed.
71  * NOTE: currently multiple virtual desktops are not implemented;
72  * this implementation always returns a #Garray with a single
73  * #AtspiAccessible desktop.
74  *
75  * Returns: (transfer full): a #GArray of desktops.
76  **/
77 GArray *
78 atspi_get_desktop_list ()
79 {
80   GArray *array = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
81   AtspiAccessible *desktop;
82
83   desktop = _atspi_ref_accessible (atspi_bus_registry, atspi_path_root);
84   if (array)
85     g_array_index (array, AtspiAccessible *, 0) = desktop;
86   return array;
87 }
88
89 /**
90  * atspi_register_keystroke_listener:
91  * @listener:  a pointer to the #AtspiDeviceListener for which
92  *             keystroke events are requested.
93  * @key_set: (element-type AtspiKeyDefinition) (allow-none): a pointer to the
94  *        #AtspiKeyDefinition array indicating which keystroke events are
95  *        requested, or NULL
96  *        to indicate that all keycodes and keyvals for the specified
97  *        modifier set are to be included.
98  * @modmask:   an #AtspiKeyMaskType mask indicating which
99  *             key event modifiers must be set in combination with @keys,
100  *             events will only be reported for key events for which all
101  *             modifiers in @modmask are set.  If you wish to listen for
102  *             events with multiple modifier combinations, you must call
103  *             #atspi_register_keystroke_listener once for each
104  *             combination.
105  * @event_types: an #AtspiKeyMaskType mask indicating which
106  *             types of key events are requested (%ATSPI_KEY_PRESSED etc.).
107  * @sync_type: an #AtspiKeyListenerSyncType parameter indicating
108  *             the behavior of the notification/listener transaction.
109  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
110  *             
111  * Registers a listener for keystroke events, either pre-emptively for
112  *             all windows (%ATSPI_KEYLISTENER_ALL_WINDOWS),
113  *             non-preemptively (%ATSPI_KEYLISTENER_NOSYNC), or
114  *             pre-emptively at the toolkit level (%ATSPI_KEYLISTENER_CANCONSUME).
115  *             If ALL_WINDOWS or CANCONSUME are used, the event is consumed
116  *             upon receipt if one of @listener's callbacks returns %TRUE 
117  *             (other sync_type values may be available in the future).
118  *
119  * Returns: %TRUE if successful, otherwise %FALSE.
120  **/
121 gboolean
122 atspi_register_keystroke_listener (AtspiDeviceListener  *listener,
123                                          GArray             *key_set,
124                                          AtspiKeyMaskType         modmask,
125                                          AtspiKeyEventMask        event_types,
126                                          gint sync_type, GError **error)
127 {
128   GArray *d_key_set;
129   gchar *path = _atspi_device_listener_get_path (listener);
130   gint                                i;
131   dbus_uint32_t d_modmask = modmask;
132   dbus_uint32_t d_event_types = event_types;
133   AtspiEventListenerMode     listener_mode;
134   gboolean                          retval = FALSE;
135   DBusError d_error;
136
137   if (!listener)
138     {
139       return retval;
140     }
141
142   /* copy the keyval filter values from the C api into the DBind KeySet */
143   if (key_set)
144     {
145       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), key_set->len);
146       d_key_set->len = key_set->len;
147       for (i = 0; i < key_set->len; ++i)
148         {
149           AtspiKeyDefinition *kd =  ((AtspiKeyDefinition *) key_set->data) + i;
150           AtspiKeyDefinition *d_kd =  ((AtspiKeyDefinition *) d_key_set->data) + i;
151           d_kd->keycode = kd->keycode;
152           d_kd->keysym = kd->keysym;
153           if (kd->keystring)
154             {
155               d_kd->keystring = kd->keystring;
156             } 
157           else 
158             {
159               d_kd->keystring = "";
160             }
161         }
162     }
163   else
164     {
165       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), 0);
166     }
167         
168   listener_mode.synchronous =
169           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_SYNCHRONOUS)!=0);
170   listener_mode.preemptive =
171           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_CANCONSUME)!=0);
172   listener_mode.global =
173           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_ALL_WINDOWS)!=0);
174
175   dbus_error_init (&d_error);
176   dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "RegisterKeystrokeListener", &d_error, "oa(iisi)uu(bbb)=>b", path, d_key_set, d_modmask, d_event_types, &listener_mode, &retval);
177   if (dbus_error_is_set (&d_error))
178     {
179       g_warning ("RegisterKeystrokeListener failed: %s", d_error.message);
180       dbus_error_free (&d_error);
181     }
182
183   g_array_free (d_key_set, TRUE);
184   g_free (path);
185
186   return retval;
187 }
188
189 /**
190  * atspi_deregister_keystroke_listener:
191  * @listener: a pointer to the #AtspiDeviceListener for which
192  *            keystroke events are requested.
193  * @key_set: (element-type AtspiKeyDefinition) (allow-none): a pointer to the
194  *        #AtspiKeyDefinition array indicating which keystroke events are
195  *        requested, or %NULL
196  *        to indicate that all keycodes and keyvals for the specified
197  *        modifier set are to be included.
198  * @modmask:  the key modifier mask for which this listener is to be
199  *            'deregistered' (of type #AtspiKeyMaskType).
200  * @event_types: an #AtspiKeyMaskType mask indicating which
201  *             types of key events were requested (%ATSPI_KEY_PRESSED, etc.).
202  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
203  *
204  * Removes a keystroke event listener from the registry's listener queue,
205  *            ceasing notification of events with modifiers matching @modmask.
206  *
207  * Returns: %TRUE if successful, otherwise %FALSE.
208  **/
209 gboolean
210 atspi_deregister_keystroke_listener (AtspiDeviceListener *listener,
211                                      GArray              *key_set,
212                                      AtspiKeyMaskType     modmask,
213                                      AtspiKeyEventMask    event_types,
214                                      GError             **error)
215 {
216   GArray *d_key_set;
217   gchar *path = _atspi_device_listener_get_path (listener);
218   gint i;
219   dbus_uint32_t d_modmask = modmask;
220   dbus_uint32_t d_event_types = event_types;
221   DBusError d_error;
222
223   dbus_error_init (&d_error);
224   if (!listener)
225     {
226       return FALSE;
227     }
228
229   /* copy the keyval filter values from the C api into the DBind KeySet */
230   if (key_set)
231     {
232       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), key_set->len);
233       d_key_set->len = key_set->len;
234       for (i = 0; i < key_set->len; ++i)
235         {
236           AtspiKeyDefinition *kd =  ((AtspiKeyDefinition *) key_set->data) + i;
237           AtspiKeyDefinition *d_kd =  ((AtspiKeyDefinition *) d_key_set->data) + i;
238           d_kd->keycode = kd->keycode;
239           d_kd->keysym = kd->keysym;
240           if (kd->keystring)
241             {
242               d_kd->keystring = kd->keystring;
243             } 
244           else 
245             {
246               d_kd->keystring = "";
247             }
248         }
249     }
250   else
251     {
252       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), 0);
253     }
254
255   dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry,
256                                atspi_path_dec, atspi_interface_dec,
257                                "DeregisterKeystrokeListener", &d_error,
258                                "oa(iisi)uu", path, d_key_set, d_modmask,
259                                d_event_types);
260   if (dbus_error_is_set (&d_error))
261     {
262       g_warning ("DeregisterKeystrokeListener failed: %s", d_error.message);
263       dbus_error_free (&d_error);
264     }
265
266   g_array_free (d_key_set, TRUE);
267   g_free (path);
268   return TRUE;
269 }
270
271 /**
272  * atspi_register_device_event_listener:
273  * @listener:  a pointer to the #AtspiDeviceListener which requests
274  *             the events.
275  * @event_types: an #AtspiDeviceEventMask mask indicating which
276  *             types of key events are requested (%ATSPI_KEY_PRESSED, etc.).
277  * @filter: Unused parameter.
278  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
279  *             
280  * Registers a listener for device events, for instance button events.
281  *
282  * Returns: %TRUE if successful, otherwise %FALSE.
283  **/
284 gboolean
285 atspi_register_device_event_listener (AtspiDeviceListener  *listener,
286                                  AtspiDeviceEventMask  event_types,
287                                  void                      *filter, GError **error)
288 {
289   gboolean                          retval = FALSE;
290   dbus_uint32_t d_event_types = event_types;
291   gchar *path = _atspi_device_listener_get_path (listener);
292   DBusError d_error;
293
294   dbus_error_init (&d_error);
295   if (!listener)
296     {
297       return retval;
298     }
299
300     dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "RegisterDeviceEventListener", &d_error, "ou=>b", path, d_event_types, &retval);
301     if (dbus_error_is_set (&d_error))
302       {
303         g_warning ("RegisterDeviceEventListener failed: %s", d_error.message);
304         dbus_error_free (&d_error);
305       }
306
307   g_free (path);
308   return retval;
309 }
310
311 /**
312  * atspi_deregister_device_event_listener:
313  * @listener: a pointer to the #AtspiDeviceListener for which
314  *            device events are requested.
315  * @filter: Unused parameter.
316  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
317  *
318  * Removes a device event listener from the registry's listener queue,
319  *            ceasing notification of events of the specified type.
320  *
321  * Returns: %TRUE if successful, otherwise %FALSE.
322  **/
323 gboolean
324 atspi_deregister_device_event_listener (AtspiDeviceListener *listener,
325                                    void                     *filter, GError **error)
326 {
327   dbus_uint32_t event_types = 0;
328   gchar *path = _atspi_device_listener_get_path (listener);
329   DBusError d_error;
330
331   dbus_error_init (&d_error);
332
333   if (!listener)
334     {
335       return FALSE;
336     }
337
338   event_types |= (1 << ATSPI_BUTTON_PRESSED_EVENT);
339   event_types |= (1 << ATSPI_BUTTON_RELEASED_EVENT);
340
341   dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "DeregisterDeviceEventListener", &d_error, "ou", path, event_types);
342   if (dbus_error_is_set (&d_error))
343     {
344       g_warning ("DeregisterDeviceEventListener failed: %s", d_error.message);
345       dbus_error_free (&d_error);
346     }
347
348   g_free (path);
349   return TRUE;
350 }
351
352 /**
353  * atspi_generate_keyboard_event:
354  * @keyval: a #gint indicating the keycode or keysym of the key event
355  *           being synthesized.
356  * @keystring: (allow-none): an (optional) UTF-8 string which, if
357  *           @synth_type is %ATSPI_KEY_STRING, indicates a 'composed'
358  *           keyboard input string being synthesized; this type of
359  *           keyboard event synthesis does not emulate hardware
360  *           keypresses but injects the string as though a composing
361  *           input method (such as XIM) were used.
362  * @synth_type: an #AtspiKeySynthType flag indicating whether @keyval
363  *           is to be interpreted as a keysym rather than a keycode
364  *           (%ATSPI_KEY_SYM) or a string (%ATSPI_KEY_STRING), or
365  *           whether to synthesize %ATSPI_KEY_PRESS,
366  *           %ATSPI_KEY_RELEASE, or both (%ATSPI_KEY_PRESSRELEASE).
367  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
368  *
369  * Synthesizes a keyboard event (as if a hardware keyboard event occurred in the
370  * current UI context).
371  *
372  * Returns: %TRUE if successful, otherwise %FALSE.
373  **/
374 gboolean
375 atspi_generate_keyboard_event (glong keyval,
376                            const gchar *keystring,
377                            AtspiKeySynthType synth_type, GError **error)
378 {
379   dbus_uint32_t d_synth_type = synth_type;
380   dbus_int32_t d_keyval = keyval;
381   DBusError d_error;
382
383   dbus_error_init (&d_error);
384   if (!keystring)
385     keystring = "";
386   dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "GenerateKeyboardEvent", &d_error, "isu", d_keyval, keystring, d_synth_type);
387   if (dbus_error_is_set (&d_error))
388     {
389       g_warning ("GenerateKeyboardEvent failed: %s", d_error.message);
390       dbus_error_free (&d_error);
391     }
392
393   return TRUE;
394 }
395
396 /**
397  * atspi_generate_mouse_event:
398  * @x: a #glong indicating the screen x coordinate of the mouse event.
399  * @y: a #glong indicating the screen y coordinate of the mouse event.
400  * @name: a string indicating which mouse event to be synthesized
401  *        (e.g. "b1p", "b1c", "b2r", "rel", "abs").
402  * @error: (allow-none): a pointer to a %NULL #GError pointer, or %NULL
403  *
404  * Synthesizes a mouse event at a specific screen coordinate.
405  * Most AT clients should use the #AccessibleAction interface when
406  * tempted to generate mouse events, rather than this method.
407  * Event names: b1p = button 1 press; b2r = button 2 release;
408  *              b3c = button 3 click; b2d = button 2 double-click;
409  *              abs = absolute motion; rel = relative motion.
410  *
411  * Returns: %TRUE if successful, otherwise %FALSE.
412  **/
413 gboolean
414 atspi_generate_mouse_event (glong x, glong y, const gchar *name, GError **error)
415 {
416   dbus_int32_t d_x = x, d_y = y;
417   DBusError d_error;
418
419   dbus_error_init (&d_error);
420   dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry,
421                                atspi_path_dec, atspi_interface_dec,
422                                "GenerateMouseEvent", &d_error, "iis",
423                                d_x, d_y, name);
424   if (dbus_error_is_set (&d_error))
425     {
426       g_warning ("GenerateMouseEvent failed: %s", d_error.message);
427       dbus_error_free (&d_error);
428     }
429
430   return TRUE;
431 }
432
433 AtspiKeyDefinition *
434 atspi_key_definition_copy (AtspiKeyDefinition *src)
435 {
436   AtspiKeyDefinition *dst;
437
438   dst = g_new0 (AtspiKeyDefinition, 1);
439   dst->keycode = src->keycode;
440   dst->keysym = src->keysym;
441   if (src->keystring)
442     dst->keystring = g_strdup (src->keystring);
443   dst->unused = src->unused;
444   return dst;
445 }
446
447 void
448 atspi_key_definition_free (AtspiKeyDefinition *kd)
449 {
450   if (kd->keystring)
451     g_free (kd->keystring);
452   g_free (kd);
453 }
454
455 G_DEFINE_BOXED_TYPE (AtspiKeyDefinition, atspi_key_definition, atspi_key_definition_copy, atspi_key_definition_free)