2001-12-10 Michael Meeks <michael@ximian.com>
[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  * 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  **/
84 SPIBoolean
85 registerGlobalEventListener (AccessibleEventListener *listener,
86                              const char              *eventType)
87 {
88   SPIBoolean retval;
89
90   Accessibility_Registry_registerGlobalEventListener (
91                          cspi_registry (),
92                          (Accessibility_EventListener)
93                             BONOBO_OBJREF (bonobo_object (listener)),
94                          eventType,
95                          cspi_ev ());
96
97   retval = !cspi_exception ();
98  
99   return retval;
100 }
101
102 /**
103  * deregisterGlobalEventListenerAll:
104  * @listener: the #AccessibleEventListener to be registered against
105  *            an event type.
106  *
107  * deregisters an AccessibleEventListener from the registry, for all
108  *            event types it may be listening to. Use
109  *            AccessibleEventListener_unref to release the
110  *            listener reference.
111  *
112  * Returns: #TRUE if successful, otherwise #FALSE.
113  *
114  **/
115 SPIBoolean
116 deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
117 {
118   Accessibility_Registry_deregisterGlobalEventListenerAll (
119                          cspi_registry (),
120                          (Accessibility_EventListener) BONOBO_OBJREF (listener),
121                          cspi_ev ());
122
123   return !cspi_exception ();
124 }
125 /**
126  * deregisterGlobalEventListener:
127  * @listener: the #AccessibleEventListener registered against an event type.
128  * @eventType: a string specifying the event type for which this
129  *             listener is to be deregistered.
130  *
131  * deregisters an AccessibleEventListener from the registry, for a specific
132  *             event type.
133  *
134  * Returns: #TRUE if successful, otherwise #FALSE.
135  *
136  **/
137 SPIBoolean
138 deregisterGlobalEventListener (AccessibleEventListener *listener,
139                                const char              *eventType)
140 {
141   Accessibility_Registry_deregisterGlobalEventListener (
142           cspi_registry (),
143           (Accessibility_EventListener) BONOBO_OBJREF (listener),
144           (CORBA_char *) eventType,
145           cspi_ev ());
146
147   return !cspi_exception ();
148 }
149
150 /**
151  * getDesktopCount:
152  *
153  * Get the number of virtual desktops.
154  * NOTE: currently multiple virtual desktops are not implemented, this
155  *       function always returns '1'.
156  *
157  * Returns: an integer indicating the number of active virtual desktops.
158  *
159  **/
160 int
161 getDesktopCount ()
162 {
163   int retval;
164
165   retval = Accessibility_Registry_getDesktopCount (
166     cspi_registry (), cspi_ev ());
167
168   cspi_return_val_if_ev ("getDesktopCount", -1);
169
170   return retval;
171 }
172
173 /**
174  * getDesktop:
175  * @i: an integer indicating which of the accessible desktops is to be returned.
176  *
177  * Get the virtual desktop indicated by index @i.
178  * NOTE: currently multiple virtual desktops are not implemented, this
179  *       function always returns '1'.
180  *
181  * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
182  *
183  **/
184 Accessible*
185 getDesktop (int i)
186 {
187   return cspi_object_add (Accessibility_Registry_getDesktop (cspi_registry (),
188                                                              (CORBA_short) i,
189                                                              cspi_ev ()));
190 }
191
192 /**
193  * getDesktopList:
194  * @list: a pointer to an array of #Accessible objects.
195  *
196  * Get the list of virtual desktops.  On return, @list will point
197  *     to a newly-created array of virtual desktop pointers.
198  *     It is the responsibility of the caller to free this array when
199  *     it is no longer needed.
200  *
201  * Not Yet Implemented : this implementation always returns a single
202  * #Accessible desktop.
203  *
204  * Returns: an integer indicating how many virtual desktops have been
205  *          placed in the list pointed to by parameter @list.
206  **/
207 int
208 getDesktopList (Accessible **list)
209 {
210   *list = NULL;
211   return 0;
212 }
213
214 /**
215  * registerAccessibleKeystrokeListener:
216  * @listener:  a pointer to the #AccessibleKeystrokeListener for which
217  *             keystroke events are requested.
218  * @keys:      a pointer to the #AccessibleKeySet indicating which
219  *             keystroke events are requested, or #CSPI_KEYSET_ALL_KEYS.
220  * @modmask:   an #AccessibleKeyMaskType mask indicating which
221  *             key event modifiers must be set in combination with @keys,
222  *             events will only be reported for key events for which all
223  *             modifiers in @modmask are set.  If you wish to listen for
224  *             events with multiple modifier combinations you must call
225  *             registerAccessibleKeystrokeListener() once for each combination.
226  * @eventmask: an #AccessibleKeyMaskType mask indicating which
227  *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
228  * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
229  *             the behavior of the notification/listener transaction.
230  *             
231  * Register a listener for keystroke events, either pre-emptively for
232  *             all windows (CSPI_KEYLISTENER_ALL_WINDOWS), or
233  *             non-preemptively (CSPI_KEYLISTENER_NOSYNC).
234  *             ( Other sync_type values may be available in the future.)
235  **/
236 void
237 registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
238                                      AccessibleKeySet *keys,
239                                      AccessibleKeyMaskType modmask,
240                                      AccessibleKeyEventMask eventmask,
241                                      AccessibleKeyListenerSyncType sync_type)
242 {
243   gint                                i, mask;
244   Accessibility_KeySet                key_set;
245   Accessibility_KeyEventTypeSeq       key_events;
246   Accessibility_ControllerEventMask   controller_event_mask;
247   Accessibility_DeviceEventController device_event_controller;
248
249   device_event_controller = 
250     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
251
252   cspi_return_if_ev ("getting event controller");
253
254   /* copy the keyval filter values from the C api into the CORBA KeySet */
255   if (keys)
256     {
257       key_set._length = keys->len;
258       key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
259       for (i = 0; i < key_set._length; ++i)
260         {
261           /* we overload the keyset long w/keycodes, the - bit acts as a flag */
262           key_set._buffer[i] = (keys->keysyms[i]) ? keys->keysyms[i] :
263                                                  -keys->keycodes[i];
264           /* g_print ("key-set %d = %d\n", i, (int) key_set->_buffer[i]); */
265         }
266     }
267   else
268     {
269       key_set._length = 0;
270       key_set._buffer = NULL;
271     }
272         
273   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
274   mask = 1;
275   i = 0;
276   do
277     {
278       if (mask & eventmask)
279         {
280           ++i; 
281         }
282       mask <<= 1;
283     }
284   while (mask & 0xFFFF);
285   
286   key_events._buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
287   i = 0;
288   if (eventmask & SPI_KEY_PRESSED)
289     {
290       key_events._buffer[i++] = Accessibility_KEY_PRESSED;
291     }
292   if (eventmask & SPI_KEY_RELEASED)
293     {
294       key_events._buffer[i++] = Accessibility_KEY_RELEASED;
295     }
296   key_events._length = i;
297   
298   controller_event_mask.value = (CORBA_unsigned_long) modmask;
299   controller_event_mask.refcount = (CORBA_unsigned_short) 1;
300
301   Accessibility_DeviceEventController_registerKeystrokeListener (
302           device_event_controller,
303           BONOBO_OBJREF (listener),
304           &key_set,
305           &controller_event_mask,
306           &key_events,
307           (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0),
308           cspi_ev ());
309
310   bonobo_object_release_unref (device_event_controller, cspi_ev ());
311 }
312
313 /**
314  * deregisterAccessibleKeystrokeListener:
315  * @listener: a pointer to the #AccessibleKeystrokeListener for which
316  *            keystroke events are requested.
317  * @modmask:  the key modifier mask for which this listener is to be
318  *            'deregistered' (of type #AccessibleeyMaskType).
319  *
320  * Removes a keystroke event listener from the registry's listener queue,
321  *            ceasing notification of events with modifiers matching @modmask.
322  **/
323 void
324 deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
325                                        AccessibleKeyMaskType modmask)
326 {
327   Accessibility_ControllerEventMask   controller_event_mask;
328   Accessibility_KeySet                key_set;
329   Accessibility_KeyEventTypeSeq       key_events;
330   Accessibility_DeviceEventController device_event_controller;
331
332   device_event_controller = 
333     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
334
335   cspi_return_if_ev ("getting keystroke listener");
336
337   controller_event_mask.value = (CORBA_unsigned_long) modmask;
338   controller_event_mask.refcount = (CORBA_unsigned_short) 1;
339
340   key_events._buffer = NULL;
341   key_events._length = 0;
342
343   key_set._buffer = NULL;
344   key_set._length = 0;
345
346   Accessibility_DeviceEventController_deregisterKeystrokeListener (
347           device_event_controller,
348           BONOBO_OBJREF (listener),
349           &key_set,
350           &controller_event_mask,
351           &key_events,
352           (CORBA_boolean) TRUE,
353           cspi_ev ());
354
355   bonobo_object_release_unref (device_event_controller, NULL);
356 }
357
358 /**
359  * generateKeyEvent:
360  * @keyval: a long integer indicating the keycode or keysym of the key event
361  *           being synthesized.
362  * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
363  *           is to be interpreted as a keysym rather than a keycode
364  *           (CSPI_KEYSYM), or whether to synthesize
365  *           SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
366  *
367  * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
368  * current UI context).
369  *
370  **/
371 void
372 generateKeyEvent (long int keyval, AccessibleKeySynthType synth_type)
373 {
374 /* TODO: check current modifier status and
375  *  send keycode to alter, if necessary
376  */
377   Accessibility_DeviceEventController device_event_controller = 
378           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
379
380   cspi_return_if_ev ("getting event controller");
381
382   Accessibility_DeviceEventController_generateKeyEvent (device_event_controller,
383                                                         keyval,
384                                                         (unsigned long) synth_type,
385                                                         cspi_ev ());
386
387   bonobo_object_release_unref (device_event_controller, NULL);
388 }
389
390 /**
391  * generateMouseEvent:
392  * @x: a #long indicating the screen x coordinate of the mouse event.
393  * @y: a #long indicating the screen y coordinate of the mouse event.
394  * @name: a string indicating which mouse event to be synthesized
395  *        (e.g. "button1", "button2", "mousemove").
396  *
397  * Synthesize a mouse event at a specific screen coordinate.
398  * Most AT clients should use the #AccessibleAction interface when
399  * tempted to generate mouse events, rather than this method.
400  * Not Yet Implemented.
401  *
402  **/
403 void
404 generateMouseEvent (long x, long y, char *name)
405 {
406   ;
407 }
408