Merge branch 'master' into gi
[platform/upstream/at-spi2-core.git] / atspi / atspi-registry.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 /* atspi_registry.c: Global functions wrapping the registry */
25
26 #include "atspi-private.h"
27
28 static GArray *desktops;
29
30 /**
31  * atspi_get_desktop_count:
32  *
33  * Get the number of virtual desktops.
34  * NOTE: currently multiple virtual desktops are not implemented, this
35  *       function always returns '1'.
36  *
37  * Returns: an integer indicating the number of active virtual desktops.
38  **/
39 gint
40 atspi_get_desktop_count ()
41 {
42   return 1;
43 }
44
45 /**
46  * atspi_get_desktop:
47  * @i: an integer indicating which of the accessible desktops is to be returned.
48  *
49  * Get the virtual desktop indicated by index @i.
50  * NOTE: currently multiple virtual desktops are not implemented.
51  *
52  * Returns: (transfer full): a pointer to the 'i-th' virtual desktop's
53  * #AtspiAccessible representation.
54  **/
55 AtspiAccessible*
56 atspi_get_desktop (gint i)
57 {
58   if (i != 0) return NULL;
59   return _atspi_ref_accessible (atspi_bus_registry, atspi_path_root);
60 }
61
62 /**
63  * atspi_get_desktop_list:
64  *
65  * Get the list of virtual desktops.  On return, @list will point
66  *     to a newly-created, NULL terminated array of virtual desktop
67  *     pointers.
68  *     It is the responsibility of the caller to free this array when
69  *     it is no longer needed.
70  *
71  * Not Yet Implemented : this implementation always returns a single
72  * #Accessible desktop.
73  *
74  * Returns: (transfer full): a #GArray of desktops.
75  **/
76 GArray *
77 atspi_get_desktop_list ()
78 {
79   GArray *array = g_array_new (TRUE, TRUE, sizeof (AtspiAccessible *));
80   AtspiAccessible *desktop;
81
82   desktop = _atspi_ref_accessible (atspi_bus_registry, atspi_path_root);
83   if (array)
84     g_array_index (array, AtspiAccessible *, 0) = desktop;
85   return array;
86 }
87
88 /**
89  * ATSPI_KEYSET_ALL_KEYS:
90  * @ATSPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
91  *                       includes all keycodes and keyvals for the specified modifier set.
92  **/
93
94 /**
95  * atspi_register_accessible_keystroke_listener:
96  * @listener:  a pointer to the #AccessibleKeystrokeListener for which
97  *             keystroke events are requested.
98  * @key_set: (type: AtspiKeyDefinition): a pointer to the
99  *        #AccessibleKeyDefinition array indicating which keystroke events are requested, or #ATSPI_KEYSET_ALL_KEYS
100  *             to indicate that all keycodes and keyvals for the specified
101  *             modifier set are to be included.
102  * @modmask:   an #AtspiKeyMaskType mask indicating which
103  *             key event modifiers must be set in combination with @keys,
104  *             events will only be reported for key events for which all
105  *             modifiers in @modmask are set.  If you wish to listen for
106  *             events with multiple modifier combinations you must call
107  *             register_accessible_keystroke_listener() once for each
108  *             combination.
109  * @eventmask: an #AtspiKeyMaskType mask indicating which
110  *             types of key events are requested (#ATSPI_KEY_PRESSED, etc.).
111  * @sync_type: a #AtspiKeyListenerSyncType parameter indicating
112  *             the behavior of the notification/listener transaction.
113  *             
114  * Register a listener for keystroke events, either pre-emptively for
115  *             all windows (ATSPI_KEYLISTENER_ALL_WINDOWS),
116  *             non-preemptively (ATSPI_KEYLISTENER_NOSYNC), or
117  *             pre-emptively at the toolkit level (ATSPI_KEYLISTENER_CANCONSUME).
118  *             If ALL_WINDOWS or CANCONSUME are used, the event is consumed
119  *             upon receipt if one of @listener's callbacks returns #TRUE.
120  *             ( Other sync_type values may be available in the future )
121  *
122  * Returns: #TRUE if successful, otherwise #FALSE.
123  **/
124 gboolean
125 atspi_register_accessible_keystroke_listener (AtspiDeviceListener  *listener,
126                                          GArray             *key_set,
127                                          AtspiKeyMaskType         modmask,
128                                          AtspiKeyEventMask        event_types,
129                                          AtspiKeyListenerSyncType sync_type, GError **error)
130 {
131   GArray *d_key_set;
132   gchar *path = _atspi_device_listener_get_path (listener);
133   gint                                i;
134   dbus_uint32_t d_modmask = modmask;
135   dbus_uint32_t d_event_types = event_types;
136   AtspiEventListenerMode     listener_mode;
137   gboolean                          retval = FALSE;
138   DBusError d_error;
139
140   if (!listener)
141     {
142       return retval;
143     }
144
145   /* copy the keyval filter values from the C api into the DBind KeySet */
146   if (key_set)
147     {
148       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), key_set->len);
149       d_key_set->len = key_set->len;
150       for (i = 0; i < key_set->len; ++i)
151         {
152           AtspiKeyDefinition *kd =  ((AtspiKeyDefinition *) key_set->data) + i;
153           AtspiKeyDefinition *d_kd =  ((AtspiKeyDefinition *) d_key_set->data) + i;
154           d_kd->keycode = kd->keycode;
155           d_kd->keysym = kd->keysym;
156           if (kd->keystring)
157             {
158               d_kd->keystring = kd->keystring;
159             } 
160           else 
161             {
162               d_kd->keystring = "";
163             }
164         }
165     }
166   else
167     {
168       d_key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), 0);
169     }
170         
171   listener_mode.synchronous =
172           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_SYNCHRONOUS)!=0);
173   listener_mode.preemptive =
174           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_CANCONSUME)!=0);
175   listener_mode.global =
176           (dbus_bool_t) ((sync_type & ATSPI_KEYLISTENER_ALL_WINDOWS)!=0);
177
178     dbus_error_init (&d_error);
179     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);
180
181   g_array_free (key_set, TRUE);
182   g_free (path);
183
184   return retval;
185 }
186
187 /**
188  * atspi_deregister_accessible_keystroke_listener:
189  * @listener: a pointer to the #AccessibleKeystrokeListener for which
190  *            keystroke events are requested.
191  * @modmask:  the key modifier mask for which this listener is to be
192  *            'deregistered' (of type #AtspiKeyMaskType).
193  *
194  * Removes a keystroke event listener from the registry's listener queue,
195  *            ceasing notification of events with modifiers matching @modmask.
196  *
197  * Returns: #TRUE if successful, otherwise #FALSE.
198  **/
199 gboolean
200 atspi_deregister_accessible_keystroke_listener (AtspiDeviceListener *listener,
201                                            AtspiKeyMaskType        modmask, AtspiKeyEventMask event_types, GError **error)
202 {
203   gchar *path = _atspi_device_listener_get_path (listener);
204   GArray *key_set;
205   dbus_uint32_t d_modmask = modmask;
206   dbus_uint32_t d_event_types = event_types;
207   DBusError d_error;
208
209   dbus_error_init (&d_error);
210   if (!listener)
211     {
212       return FALSE;
213     }
214
215       key_set = g_array_sized_new (FALSE, TRUE, sizeof (AtspiKeyDefinition), 0);
216     dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "DeregisterKeystrokeListener", &d_error, "oa(iisi)uu", path, &key_set, d_modmask, d_event_types);
217   g_free (path);
218   return TRUE;
219 }
220
221 /**
222  * atspi_register_device_event_listener:
223  * @listener:  a pointer to the #AtspiDeviceListener which requests
224  *             the events.
225  * @event_types: an #AtspiDeviceEventMask mask indicating which
226  *             types of key events are requested (#ATSPI_KEY_PRESSED, etc.).
227  * @filter: Unused parameter.
228  *             
229  * Register a listener for device events, for instance button events.
230  *
231  * Returns: #TRUE if successful, otherwise #FALSE.
232  **/
233 gboolean
234 atspi_register_device_event_listener (AtspiDeviceListener  *listener,
235                                  AtspiDeviceEventMask  event_types,
236                                  void                      *filter, GError **error)
237 {
238   gboolean                          retval = FALSE;
239   dbus_uint32_t d_event_types = event_types;
240   gint                                i;
241   gchar *path = _atspi_device_listener_get_path (listener);
242   DBusError d_error;
243
244   dbus_error_init (&d_error);
245   if (!listener)
246     {
247       return retval;
248     }
249
250     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);
251   g_free (path);
252   return retval;
253 }
254
255 /**
256  * atspi_deregister_device_event_listener:
257  * @listener: a pointer to the #AtspiDeviceListener for which
258  *            device events are requested.
259  * @filter: Unused parameter.
260  *
261  * Removes a device event listener from the registry's listener queue,
262  *            ceasing notification of events of the specified type.
263  *
264  * Returns: #TRUE if successful, otherwise #FALSE.
265  **/
266 gboolean
267 atspi_deregister_device_event_listener (AtspiDeviceListener *listener,
268                                    void                     *filter, GError **error)
269 {
270   dbus_uint32_t event_types = 0;
271   gchar *path = _atspi_device_listener_get_path (listener);
272   DBusError d_error;
273
274   dbus_error_init (&d_error);
275
276   if (!listener)
277     {
278       return FALSE;
279     }
280
281   event_types |= (1 << ATSPI_BUTTON_PRESSED_EVENT);
282   event_types |= (1 << ATSPI_BUTTON_RELEASED_EVENT);
283
284     dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "DeregisterDeviceEventListener", &d_error, "ou", path, event_types);
285   g_free (path);
286   return TRUE;
287 }
288
289 /**
290  * atspi_generate_keyboard_event:
291  * @keyval: a long integer indicating the keycode or keysym of the key event
292  *           being synthesized.
293  * @keystring: an (optional) UTF-8 string which, if @keyval is NULL,
294  *           indicates a 'composed' keyboard input string which is 
295  *           being synthesized; this type of keyboard event synthesis does
296  *           not emulate hardware keypresses but injects the string 
297  *           as though a composing input method (such as XIM) were used.
298  * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
299  *           is to be interpreted as a keysym rather than a keycode
300  *           (ATSPI_KEYSYM), or whether to synthesize
301  *           ATSPI_KEY_PRESS, ATSPI_KEY_RELEASE, or both (ATSPI_KEY_PRESSRELEASE).
302  *
303  * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
304  * current UI context).
305  *
306  * Returns: #TRUE if successful, otherwise #FALSE.
307  **/
308 gboolean
309 atspi_generate_keyboard_event (glong keyval,
310                            const gchar *keystring,
311                            AtspiKeySynthType synth_type, GError **error)
312 {
313   dbus_uint32_t d_synth_type = synth_type;
314   dbus_int32_t d_keyval = keyval;
315   DBusError d_error;
316
317   dbus_error_init (&d_error);
318   if (!keystring) keystring = "";
319     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);
320
321   return TRUE;
322 }
323
324 /**
325  * atspi_generate_mouse_event:
326  * @x: a #long indicating the screen x coordinate of the mouse event.
327  * @y: a #long indicating the screen y coordinate of the mouse event.
328  * @name: a string indicating which mouse event to be synthesized
329  *        (e.g. "b1p", "b1c", "b2r", "rel", "abs").
330  *
331  * Synthesize a mouse event at a specific screen coordinate.
332  * Most AT clients should use the #AccessibleAction interface when
333  * tempted to generate mouse events, rather than this method.
334  * Event names: b1p = button 1 press; b2r = button 2 release;
335  *              b3c = button 3 click; b2d = button 2 double-click;
336  *              abs = absolute motion; rel = relative motion.
337  *
338  * Returns: #TRUE if successful, otherwise #FALSE.
339  **/
340 gboolean
341 atspi_generate_mouse_event (glong x, glong y, const gchar *name, GError **error)
342 {
343   dbus_int32_t dbus_x = x, dbus__y = y;
344   DBusError d_error;
345
346   dbus_error_init (&d_error);
347     dbind_method_call_reentrant (_atspi_bus(), atspi_bus_registry, atspi_path_dec, atspi_interface_dec, "GenerateMouseEvent", &d_error, "iis", x, y, name);
348   return TRUE;
349 }