Added methods for Component Layer and MDI Z-Order information (see
[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 #include <cspi/spi-private.h>
24
25 /*
26  *
27  * Global functions serviced by the registry
28  *
29  */
30
31 #if 0
32 /* static stuff used only by registry C bindings */
33 static GList *key_listeners = NULL;
34 static Display *display = NULL;
35 #endif
36
37 /**
38  * registerGlobalEventListener:
39  * @listener: the #AccessibleEventListener to be registered against an
40  *            event type.
41  * @eventType: a character string indicating the type of events for which
42  *            notification is requested.  Format is
43  *            EventClass:major_type:minor_type:detail
44  *            where all subfields other than EventClass are optional.
45  *            EventClasses include "object", "window", "mouse",
46  *            and toolkit events (e.g. "Gtk", "AWT").
47  *            Examples: "focus:", "Gtk:GtkWidget:button_press_event".
48  *
49  * Legal object event types:
50  *
51  *    (property change events)
52  *
53  *            object:property-change
54  *            object:property-change:accessible-name
55  *            object:property-change:accessible-state
56  *            object:property-change:accessible-description
57  *            object:property-change:accessible-parent
58  *            object:property-change:accessible-value
59  *            object:property-change:accessible-role
60  *            object:property-change:accessible-table-caption
61  *            object:property-change:accessible-table-column-description
62  *            object:property-change:accessible-table-column-header
63  *            object:property-change:accessible-table-row-description
64  *            object:property-change:accessible-table-row-header
65  *            object:property-change:accessible-table-summary
66  *
67  *    (other object events)
68  *
69  *            object:children-changed
70  *            object:visible-data-changed
71  *            object:selection-changed
72  *            object:text-selection-changed
73  *            object:text-changed
74  *            object:text-caret-moved
75  *            object:row-inserted
76  *            object:row-reordered
77  *            object:row-deleted
78  *            object:column-inserted
79  *            object:column-reordered
80  *            object:column-deleted
81  *            object:model-changed
82  *
83  * NOTE: this string may be UTF-8, but should not contain byte value 56
84  *            (ascii ':'), except as a delimiter, since non-UTF-8 string
85  *            delimiting functions are used internally.
86  *            In general, listening to
87  *            toolkit-specific events is not recommended.
88  *
89  * Add an in-process callback function to an existing AccessibleEventListener.
90  *
91  * Returns: #TRUE if successful, otherwise #FALSE.
92  *
93  **/
94 SPIBoolean
95 registerGlobalEventListener (AccessibleEventListener *listener,
96                              char *eventType)
97 {
98   SPIBoolean retval;
99
100   Accessibility_Registry_registerGlobalEventListener (
101                          cspi_registry (),
102                          (Accessibility_EventListener)
103                             bonobo_object_corba_objref (bonobo_object (listener)),
104                          eventType,
105                          cspi_ev ());
106
107   retval = !cspi_exception ();
108  
109   return retval;
110 }
111
112 /**
113  * deregisterGlobalEventListenerAll:
114  * @listener: the #AccessibleEventListener to be registered against
115  *            an event type.
116  *
117  * deregisters an AccessibleEventListener from the registry, for all
118  *            event types it may be listening to.  Also unrefs the listener.
119  *            The listener cannot subsequently be reused.
120  *
121  * Returns: #TRUE if successful, otherwise #FALSE.
122  *
123  **/
124 SPIBoolean
125 deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
126 {
127   Accessibility_Registry_deregisterGlobalEventListenerAll (
128                          cspi_registry (),
129                          (Accessibility_EventListener)
130                             CORBA_Object_duplicate (
131                                     bonobo_object_corba_objref (
132                                             bonobo_object (listener)), cspi_ev ()),
133                          cspi_ev ());
134   if (!cspi_exception ())
135     {
136       bonobo_object_unref (BONOBO_OBJECT (listener));       
137       /* Would prefer that this were not a bonobo object: g_object_unref (listener);*/
138     }
139
140   return !cspi_exception ();
141 }
142 /**
143  * deregisterGlobalEventListener:
144  * @listener: the #AccessibleEventListener registered against an event type.
145  * @eventType: a string specifying the event type for which this
146  *             listener is to be deregistered.
147  *
148  * deregisters an AccessibleEventListener from the registry, for a specific
149  *             event type.
150  *
151  * Returns: #TRUE if successful, otherwise #FALSE.
152  *
153  **/
154 SPIBoolean
155 deregisterGlobalEventListener (AccessibleEventListener *listener,
156                                char *eventType)
157 {
158   Accessibility_Registry_deregisterGlobalEventListener (
159           cspi_registry (),
160           (Accessibility_EventListener)
161           CORBA_Object_duplicate (
162                   bonobo_object_corba_objref (bonobo_object (listener)), cspi_ev ()),
163           (CORBA_char *) eventType,
164           cspi_ev ());
165
166   return !cspi_exception ();
167 }
168
169 /**
170  * getDesktopCount:
171  *
172  * Get the number of virtual desktops.
173  * NOTE: currently multiple virtual desktops are not implemented, this
174  *       function always returns '1'.
175  *
176  * Returns: an integer indicating the number of active virtual desktops.
177  *
178  **/
179 int
180 getDesktopCount ()
181 {
182   return Accessibility_Registry_getDesktopCount (cspi_registry (), cspi_ev ());
183 }
184
185 /**
186  * getDesktop:
187  * @i: an integer indicating which of the accessible desktops is to be returned.
188  *
189  * Get the virtual desktop indicated by index @i.
190  * NOTE: currently multiple virtual desktops are not implemented, this
191  *       function always returns '1'.
192  *
193  * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
194  *
195  **/
196 Accessible*
197 getDesktop (int i)
198 {
199   return cspi_object_add (Accessibility_Registry_getDesktop (cspi_registry (),
200                                                              (CORBA_short) i,
201                                                              cspi_ev ()));
202 }
203
204 /**
205  * getDesktopList:
206  * @list: a pointer to an array of #Accessible objects.
207  *
208  * Get the list of virtual desktops.  On return, @list will point
209  *     to a newly-created array of virtual desktop pointers.
210  *     It is the responsibility of the caller to free this array when
211  *     it is no longer needed.
212  *
213  * Not Yet Implemented : this implementation always returns a single
214  * #Accessible desktop.
215  *
216  * Returns: an integer indicating how many virtual desktops have been
217  *          placed in the list pointed to by parameter @list.
218  **/
219 int
220 getDesktopList (Accessible **list)
221 {
222   *list = NULL;
223   return 0;
224 }
225
226 /**
227  * registerAccessibleKeystrokeListener:
228  * @listener:  a pointer to the #AccessibleKeystrokeListener for which
229  *             keystroke events are requested.
230  * @keys:      a pointer to the #AccessibleKeySet indicating which
231  *             keystroke events are requested, or #CSPI_KEYSET_ALL_KEYS.
232  * @modmask:   an #AccessibleKeyMaskType mask indicating which
233  *             key event modifiers must be set in combination with @keys,
234  *             events will only be reported for key events for which all
235  *             modifiers in @modmask are set.  If you wish to listen for
236  *             events with multiple modifier combinations you must call
237  *             registerAccessibleKeystrokeListener() once for each combination.
238  * @eventmask: an #AccessibleKeyMaskType mask indicating which
239  *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
240  * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
241  *             the behavior of the notification/listener transaction.
242  *             
243  * Register a listener for keystroke events, either pre-emptively for
244  *             all windows (CSPI_KEYLISTENER_ALL_WINDOWS), or
245  *             non-preemptively (CSPI_KEYLISTENER_NOSYNC).
246  *             ( Other sync_type values may be available in the future.)
247  **/
248 void
249 registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
250                                      AccessibleKeySet *keys,
251                                      AccessibleKeyMaskType modmask,
252                                      AccessibleKeyEventMask eventmask,
253                                      AccessibleKeyListenerSyncType sync_type)
254 {
255   Accessibility_ControllerEventMask *controller_event_mask =
256           Accessibility_ControllerEventMask__alloc();
257   Accessibility_DeviceEventController device_event_controller = 
258           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
259   Accessibility_KeySet *key_set = Accessibility_KeySet__alloc();
260   Accessibility_KeyEventTypeSeq *key_events = Accessibility_KeyEventTypeSeq__alloc();
261   Accessibility_KeystrokeListener cspi_listener_corba_ref;
262   gint i, mask;
263   Accessibility_DeviceEventController_ref (device_event_controller, cspi_ev ());
264
265   /* copy the keyval filter values from the C api into the CORBA KeySet */
266   if (keys)
267     {
268       key_set->_buffer = Accessibility_KeySet_allocbuf (
269                                                     (unsigned long) keys->len);
270       key_set->_length = (unsigned long) keys->len;
271       for (i=0; i < key_set->_length; ++i)
272         {
273           /* we overload the keyset long w/keycodes, the - bit acts as a flag */
274           key_set->_buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
275                                                  -keys->keycodes[i];
276           /* g_print ("key-set %d = %d\n", i, (int) key_set->_buffer[i]); */
277         }
278     }
279   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
280   mask=1;
281   i=0;
282   do
283     {
284       if (mask & eventmask) ++i; 
285       mask <<= 1;
286     } while (mask & 0xFFFF);
287   
288   key_events->_buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
289   i=0;
290   if (eventmask & SPI_KEY_PRESSED)
291     {
292       key_events->_buffer[i++] = Accessibility_KEY_PRESSED;
293     }
294   if (eventmask & SPI_KEY_RELEASED)
295     {
296       key_events->_buffer[i++] = Accessibility_KEY_RELEASED;
297     }
298   key_events->_length = i;
299   
300   controller_event_mask->value = (CORBA_unsigned_long) modmask;
301   controller_event_mask->refcount = (CORBA_unsigned_short) 1;
302
303   cspi_listener_corba_ref = (Accessibility_KeystrokeListener)
304           CORBA_Object_duplicate (bonobo_object_corba_objref (bonobo_object (listener)), cspi_ev ());
305   
306           Accessibility_DeviceEventController_registerKeystrokeListener (
307           device_event_controller,
308           cspi_listener_corba_ref,
309           key_set,
310           controller_event_mask,
311           key_events,
312           (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0),
313           cspi_ev ());
314 }
315
316 /**
317  * deregisterAccessibleKeystrokeListener:
318  * @listener: a pointer to the #AccessibleKeystrokeListener for which
319  *            keystroke events are requested.
320  * @modmask:  the key modifier mask for which this listener is to be
321  *            'deregistered' (of type #AccessibleeyMaskType).
322  *
323  * Removes a keystroke event listener from the registry's listener queue,
324  *            ceasing notification of events with modifiers matching @modmask.
325  **/
326 void
327 deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
328                                        AccessibleKeyMaskType modmask)
329 {
330   Accessibility_ControllerEventMask *controller_event_mask =
331           Accessibility_ControllerEventMask__alloc();
332   Accessibility_DeviceEventController device_event_controller = 
333           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
334   Accessibility_KeySet *all_keys = Accessibility_KeySet__alloc();
335   Accessibility_KeyEventTypeSeq *key_events = Accessibility_KeyEventTypeSeq__alloc();
336   Accessibility_KeystrokeListener cspi_listener_corba_ref;
337   Accessibility_DeviceEventController_unref (device_event_controller, cspi_ev ());
338   controller_event_mask->value = (CORBA_unsigned_long) modmask;
339   controller_event_mask->refcount = (CORBA_unsigned_short) 1;
340
341   cspi_listener_corba_ref = (Accessibility_KeystrokeListener)
342           CORBA_Object_duplicate (BONOBO_OBJREF(listener), cspi_ev ());
343   
344   Accessibility_DeviceEventController_deregisterKeystrokeListener (
345           device_event_controller,
346           cspi_listener_corba_ref,
347           all_keys,
348           controller_event_mask,
349           key_events,
350           (CORBA_boolean) TRUE,
351           cspi_ev ());
352 }
353
354 /**
355  * generateKeyEvent:
356  * @keyval: a long integer indicating the keycode or keysym of the key event
357  *           being synthesized.
358  * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
359  *           is to be interpreted as a keysym rather than a keycode
360  *           (CSPI_KEYSYM), or whether to synthesize
361  *           SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
362  *
363  * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
364  * current UI context).
365  *
366  **/
367 void
368 generateKeyEvent (long int keyval, AccessibleKeySynthType synth_type)
369 {
370 /* TODO: check current modifier status and
371  *  send keycode to alter, if necessary
372  */
373   Accessibility_DeviceEventController device_event_controller = 
374           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
375   Accessibility_DeviceEventController_generateKeyEvent (device_event_controller,
376                                                         keyval,
377                                                         (unsigned long) synth_type,
378                                                         cspi_ev ());
379 }
380
381 /**
382  * generateMouseEvent:
383  * @x: a #long indicating the screen x coordinate of the mouse event.
384  * @y: a #long indicating the screen y coordinate of the mouse event.
385  * @name: a string indicating which mouse event to be synthesized
386  *        (e.g. "button1", "button2", "mousemove").
387  *
388  * Synthesize a mouse event at a specific screen coordinate.
389  * Most AT clients should use the #AccessibleAction interface when
390  * tempted to generate mouse events, rather than this method.
391  * Not Yet Implemented.
392  *
393  **/
394 void
395 generateMouseEvent (long x, long y, char *name)
396 {
397   ;
398 }
399