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