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