0d75803e252414f294e9bc222bac3fb8831a93e0
[platform/core/uifw/at-spi2-atk.git] / cspi / spi_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 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* spi_registry.c: Global functions wrapping the registry */
24
25 #include <cspi/spi-private.h>
26
27 /**
28  * SPI_registerGlobalEventListener:
29  * @listener: the #AccessibleEventListener to be registered against an
30  *            event type.
31  * @eventType: a character string indicating the type of events for which
32  *            notification is requested.  Format is
33  *            EventClass:major_type:minor_type:detail
34  *            where all subfields other than EventClass are optional.
35  *            EventClasses include "object", "window", "mouse",
36  *            and toolkit events (e.g. "Gtk", "AWT").
37  *            Examples: "focus:", "Gtk:GtkWidget:button_press_event".
38  *
39  * Legal object event types:
40  *
41  *    (property change events)
42  *
43  *            object:property-change
44  *            object:property-change:accessible-name
45  *            object:property-change:accessible-state
46  *            object:property-change:accessible-description
47  *            object:property-change:accessible-parent
48  *            object:property-change:accessible-value
49  *            object:property-change:accessible-role
50  *            object:property-change:accessible-table-caption
51  *            object:property-change:accessible-table-column-description
52  *            object:property-change:accessible-table-column-header
53  *            object:property-change:accessible-table-row-description
54  *            object:property-change:accessible-table-row-header
55  *            object:property-change:accessible-table-summary
56  *
57  *    (other object events)
58  *
59  *            object:children-changed
60  *            object:visible-data-changed
61  *            object:selection-changed
62  *            object:text-selection-changed
63  *            object:text-changed
64  *            object:text-caret-moved
65  *            object:row-inserted
66  *            object:row-reordered
67  *            object:row-deleted
68  *            object:column-inserted
69  *            object:column-reordered
70  *            object:column-deleted
71  *            object:model-changed
72  *
73  * NOTE: this string may be UTF-8, but should not contain byte value 56
74  *            (ascii ':'), except as a delimiter, since non-UTF-8 string
75  *            delimiting functions are used internally.
76  *            In general, listening to
77  *            toolkit-specific events is not recommended.
78  *
79  * Add an in-process callback function to an existing AccessibleEventListener.
80  *
81  * Returns: #TRUE if successful, otherwise #FALSE.
82  **/
83 SPIBoolean
84 SPI_registerGlobalEventListener (AccessibleEventListener *listener,
85                                  const char              *eventType)
86 {
87   SPIBoolean retval;
88
89   if (!listener)
90     {
91       return FALSE;
92     }
93
94   Accessibility_Registry_registerGlobalEventListener (
95     cspi_registry (),
96     cspi_event_listener_get_corba (listener),
97     eventType, cspi_ev ());
98
99   retval = !cspi_exception ();
100  
101   return retval;
102 }
103
104 /**
105  * SPI_deregisterGlobalEventListenerAll:
106  * @listener: the #AccessibleEventListener to be registered against
107  *            an event type.
108  *
109  * deregisters an AccessibleEventListener from the registry, for all
110  *            event types it may be listening to. Use
111  *            AccessibleEventListener_unref to release the
112  *            listener reference.
113  *
114  * Returns: #TRUE if successful, otherwise #FALSE.
115  **/
116 SPIBoolean
117 SPI_deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
118 {
119   if (!listener)
120     {
121       return FALSE;
122     }
123
124   Accessibility_Registry_deregisterGlobalEventListenerAll (
125     cspi_registry (),
126     cspi_event_listener_get_corba (listener),
127     cspi_ev ());
128
129   return !cspi_exception ();
130 }
131
132 /**
133  * SPI_deregisterGlobalEventListener:
134  * @listener: the #AccessibleEventListener registered against an event type.
135  * @eventType: a string specifying the event type for which this
136  *             listener is to be deregistered.
137  *
138  * deregisters an AccessibleEventListener from the registry, for a specific
139  *             event type.
140  *
141  * Returns: #TRUE if successful, otherwise #FALSE.
142  **/
143 SPIBoolean
144 SPI_deregisterGlobalEventListener (AccessibleEventListener *listener,
145                                    const char              *eventType)
146 {
147   if (!listener)
148     {
149       return FALSE;
150     }
151
152   Accessibility_Registry_deregisterGlobalEventListener (
153     cspi_registry (), 
154     cspi_event_listener_get_corba (listener),
155     (CORBA_char *) eventType, cspi_ev ());
156
157   return !cspi_exception ();
158 }
159
160 /**
161  * SPI_getDesktopCount:
162  *
163  * Get the number of virtual desktops.
164  * NOTE: currently multiple virtual desktops are not implemented, this
165  *       function always returns '1'.
166  *
167  * Returns: an integer indicating the number of active virtual desktops.
168  **/
169 int
170 SPI_getDesktopCount ()
171 {
172   int retval;
173
174   retval = Accessibility_Registry_getDesktopCount (
175     cspi_registry (), cspi_ev ());
176
177   cspi_return_val_if_ev ("getDesktopCount", -1);
178
179   return retval;
180 }
181
182 /**
183  * SPI_getDesktop:
184  * @i: an integer indicating which of the accessible desktops is to be returned.
185  *
186  * Get the virtual desktop indicated by index @i.
187  * NOTE: currently multiple virtual desktops are not implemented, this
188  *       function always returns '1'.
189  *
190  * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
191  **/
192 Accessible*
193 SPI_getDesktop (int i)
194 {
195   return cspi_object_add (
196     Accessibility_Registry_getDesktop (
197       cspi_registry (), (CORBA_short) i, cspi_ev ()));
198 }
199
200 /**
201  * SPI_getDesktopList:
202  * @list: a pointer to an array of #Accessible objects.
203  *
204  * Get the list of virtual desktops.  On return, @list will point
205  *     to a newly-created array of virtual desktop pointers.
206  *     It is the responsibility of the caller to free this array when
207  *     it is no longer needed.
208  *
209  * Not Yet Implemented : this implementation always returns a single
210  * #Accessible desktop.
211  *
212  * Returns: an integer indicating how many virtual desktops have been
213  *          placed in the list pointed to by parameter @list.
214  **/
215 int
216 SPI_getDesktopList (Accessible **list)
217 {
218   *list = NULL;
219   return 0;
220 }
221
222 /**
223  * SPI_registerAccessibleKeystrokeListener:
224  * @listener:  a pointer to the #AccessibleKeystrokeListener for which
225  *             keystroke events are requested.
226  * @keys:      a pointer to the #AccessibleKeySet indicating which
227  *             keystroke events are requested, or #CSPI_KEYSET_ALL_KEYS.
228  * @modmask:   an #AccessibleKeyMaskType mask indicating which
229  *             key event modifiers must be set in combination with @keys,
230  *             events will only be reported for key events for which all
231  *             modifiers in @modmask are set.  If you wish to listen for
232  *             events with multiple modifier combinations you must call
233  *             registerAccessibleKeystrokeListener() once for each combination.
234  * @eventmask: an #AccessibleKeyMaskType mask indicating which
235  *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
236  * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
237  *             the behavior of the notification/listener transaction.
238  *             
239  * Register a listener for keystroke events, either pre-emptively for
240  *             all windows (CSPI_KEYLISTENER_ALL_WINDOWS), or
241  *             non-preemptively (CSPI_KEYLISTENER_NOSYNC).
242  *             ( Other sync_type values may be available in the future.)
243  *
244  * Returns: #TRUE if successful, otherwise #FALSE.
245  **/
246 SPIBoolean
247 SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
248                                          AccessibleKeySet *keys,
249                                          AccessibleKeyMaskType modmask,
250                                          AccessibleKeyEventMask eventmask,
251                                          AccessibleKeyListenerSyncType sync_type)
252 {
253   gint                                i, mask;
254   Accessibility_KeySet                key_set;
255   Accessibility_KeyEventTypeSeq       key_events;
256   Accessibility_ControllerEventMask   controller_event_mask;
257   Accessibility_DeviceEventController device_event_controller;
258
259   if (!listener)
260     {
261       return FALSE;
262     }
263
264   device_event_controller = 
265     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
266
267   cspi_return_val_if_ev ("getting event controller", FALSE);
268
269   /* copy the keyval filter values from the C api into the CORBA KeySet */
270   if (keys)
271     {
272       key_set._length = keys->len;
273       key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
274       for (i = 0; i < key_set._length; ++i)
275         {
276           /* we overload the keyset long w/keycodes, the - bit acts as a flag */
277           key_set._buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
278                                                   - keys->keycodes[i];
279           /* fprintf (stderr, "key-set %d = %d\n", i, (int) key_set->_buffer[i]); */
280         }
281     }
282   else
283     {
284       key_set._length = 0;
285       key_set._buffer = NULL;
286     }
287         
288   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
289   mask = 1;
290   i = 0;
291   do
292     {
293       if (mask & eventmask)
294         {
295           ++i; 
296         }
297       mask <<= 1;
298     }
299   while (mask & 0xFFFF);
300   
301   key_events._buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
302   i = 0;
303   if (eventmask & SPI_KEY_PRESSED)
304     {
305       key_events._buffer[i++] = Accessibility_KEY_PRESSED;
306     }
307   if (eventmask & SPI_KEY_RELEASED)
308     {
309       key_events._buffer[i++] = Accessibility_KEY_RELEASED;
310     }
311   key_events._length = i;
312   
313   controller_event_mask = (CORBA_unsigned_long) modmask;
314
315   Accessibility_DeviceEventController_registerKeystrokeListener (
316     device_event_controller,
317     cspi_event_listener_get_corba (listener),
318     &key_set,
319     controller_event_mask,
320     &key_events,
321     ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0) ? CORBA_TRUE : CORBA_FALSE,
322     cspi_ev ());
323
324   cspi_return_val_if_ev ("registering keystroke listener", FALSE);
325
326   cspi_release_unref (device_event_controller);
327
328   return TRUE;
329 }
330
331 /**
332  * SPI_deregisterAccessibleKeystrokeListener:
333  * @listener: a pointer to the #AccessibleKeystrokeListener for which
334  *            keystroke events are requested.
335  * @modmask:  the key modifier mask for which this listener is to be
336  *            'deregistered' (of type #AccessibleeyMaskType).
337  *
338  * Removes a keystroke event listener from the registry's listener queue,
339  *            ceasing notification of events with modifiers matching @modmask.
340  *
341  * Returns: #TRUE if successful, otherwise #FALSE.
342  **/
343 SPIBoolean
344 SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
345                                            AccessibleKeyMaskType modmask)
346 {
347   Accessibility_ControllerEventMask   controller_event_mask;
348   Accessibility_KeySet                key_set;
349   Accessibility_KeyEventTypeSeq       key_events;
350   Accessibility_DeviceEventController device_event_controller;
351
352   if (!listener)
353     {
354       return FALSE;
355     }
356
357   device_event_controller = 
358     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
359
360   cspi_return_val_if_ev ("getting keystroke listener", FALSE);
361
362   controller_event_mask = (CORBA_unsigned_long) modmask;
363
364   key_events._buffer = NULL;
365   key_events._length = 0;
366
367   key_set._buffer = NULL;
368   key_set._length = 0;
369
370   Accessibility_DeviceEventController_deregisterKeystrokeListener (
371     device_event_controller,
372     cspi_event_listener_get_corba (listener),
373     &key_set,
374     controller_event_mask,
375     &key_events,
376     (CORBA_boolean) TRUE,
377     cspi_ev ());
378
379   cspi_release_unref (device_event_controller);
380
381   return TRUE;
382 }
383
384 /**
385  * SPI_generateKeyEvent:
386  * @keyval: a long integer indicating the keycode or keysym of the key event
387  *           being synthesized.
388  * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
389  *           is to be interpreted as a keysym rather than a keycode
390  *           (CSPI_KEYSYM), or whether to synthesize
391  *           SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
392  *
393  * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
394  * current UI context).
395  *
396  * Returns: #TRUE if successful, otherwise #FALSE.
397  **/
398 SPIBoolean
399 SPI_generateKeyEvent (long int keyval, AccessibleKeySynthType synth_type)
400 {
401 /* TODO: check current modifier status and
402  *  send keycode to alter, if necessary
403  */
404   Accessibility_DeviceEventController device_event_controller = 
405           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
406
407   g_print ("keyval %d\n", (int) keyval);
408   cspi_return_val_if_ev ("getting event controller", FALSE);
409
410   Accessibility_DeviceEventController_generateKeyEvent (device_event_controller,
411                                                         keyval,
412                                                         (unsigned long) synth_type,
413                                                         cspi_ev ());
414
415   cspi_release_unref (device_event_controller);
416
417   return TRUE;
418 }
419
420 /**
421  * SPI_generateMouseEvent:
422  * @x: a #long indicating the screen x coordinate of the mouse event.
423  * @y: a #long indicating the screen y coordinate of the mouse event.
424  * @name: a string indicating which mouse event to be synthesized
425  *        (e.g. "button1", "button2", "mousemove").
426  *
427  * Synthesize a mouse event at a specific screen coordinate.
428  * Most AT clients should use the #AccessibleAction interface when
429  * tempted to generate mouse events, rather than this method.
430  * Not Yet Implemented.
431  *
432  * Returns: #TRUE if successful, otherwise #FALSE.
433  **/
434 SPIBoolean
435 SPI_generateMouseEvent (long x, long y, char *name)
436 {
437   return FALSE;
438 }
439