Changes to introspection generation to remove DOCTYPE and XML
[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, 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 /* spi_registry.c: Global functions wrapping the registry */
25
26 #include <cspi/spi-private.h>
27
28 /**
29  * SPI_registerGlobalEventListener:
30  * @listener: the #AccessibleEventListener to be registered against an
31  *            event type.
32  * @eventType: a character string indicating the type of events for which
33  *            notification is requested.  Format is
34  *            EventClass:major_type:minor_type:detail
35  *            where all subfields other than EventClass are optional.
36  *            EventClasses include "object", "window", "mouse",
37  *            and toolkit events (e.g. "Gtk", "AWT").
38  *            Examples: "focus:", "Gtk:GtkWidget:button_press_event".
39  *
40  * Legal object event types:
41  *
42  *    (property change events)
43  *
44  *            object:property-change
45  *            object:property-change:accessible-name
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:state-changed 
60  *            object:children-changed
61  *            object:visible-data-changed
62  *            object:selection-changed
63  *            object:text-selection-changed
64  *            object:text-changed
65  *            object:text-caret-moved
66  *            object:row-inserted
67  *            object:row-reordered
68  *            object:row-deleted
69  *            object:column-inserted
70  *            object:column-reordered
71  *            object:column-deleted
72  *            object:model-changed
73  *            object:active-descendant-changed
74  *
75  *  (window events)
76  *
77  *            window:minimize
78  *            window:maximize
79  *            window:restore
80  *            window:close
81  *            window:create
82  *            window:reparent
83  *            window:desktop-create
84  *            window:desktop-destroy
85  *            window:activate
86  *            window:deactivate
87  *            window:raise
88  *            window:lower
89  *            window:move
90  *            window:resize
91  *            window:shade
92  *            window:unshade
93  *            window:restyle
94  *
95  *  (other events)
96  *
97  *            focus:
98  *            mouse:abs
99  *            mouse:rel
100  *            mouse:b1p
101  *            mouse:b1r
102  *            mouse:b2p
103  *            mouse:b2r
104  *            mouse:b3p
105  *            mouse:b3r
106  *
107  * NOTE: this string may be UTF-8, but should not contain byte value 56
108  *            (ascii ':'), except as a delimiter, since non-UTF-8 string
109  *            delimiting functions are used internally.
110  *            In general, listening to
111  *            toolkit-specific events is not recommended.
112  *
113  * Add an in-process callback function to an existing AccessibleEventListener.
114  *
115  * Returns: #TRUE if successful, otherwise #FALSE.
116  **/
117 SPIBoolean
118 SPI_registerGlobalEventListener (AccessibleEventListener *listener,
119                                  const char              *eventType)
120 {
121   if (!listener)
122     {
123       return FALSE;
124     }
125
126   Accessibility_Registry_registerGlobalEventListener (
127     cspi_registry (),
128     cspi_event_listener_get_corba (listener),
129     eventType, cspi_ev ());
130
131   return  !cspi_exception ();
132 }
133
134 /**
135  * SPI_deregisterGlobalEventListenerAll:
136  * @listener: the #AccessibleEventListener to be registered against
137  *            an event type.
138  *
139  * deregisters an AccessibleEventListener from the registry, for all
140  *            event types it may be listening to. Use
141  *            AccessibleEventListener_unref to release the
142  *            listener reference.
143  *
144  * Returns: #TRUE if successful, otherwise #FALSE.
145  **/
146 SPIBoolean
147 SPI_deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
148 {
149   if (!listener)
150     {
151       return FALSE;
152     }
153
154   Accessibility_Registry_deregisterGlobalEventListenerAll (
155     cspi_registry (),
156     cspi_event_listener_get_corba (listener),
157     cspi_ev ());
158
159   return !cspi_exception ();
160 }
161
162 /**
163  * SPI_deregisterGlobalEventListener:
164  * @listener: the #AccessibleEventListener registered against an event type.
165  * @eventType: a string specifying the event type for which this
166  *             listener is to be deregistered.
167  *
168  * deregisters an AccessibleEventListener from the registry, for a specific
169  *             event type.
170  *
171  * Returns: #TRUE if successful, otherwise #FALSE.
172  **/
173 SPIBoolean
174 SPI_deregisterGlobalEventListener (AccessibleEventListener *listener,
175                                    const char              *eventType)
176 {
177   if (!listener)
178     {
179       return FALSE;
180     }
181
182   Accessibility_Registry_deregisterGlobalEventListener (
183     cspi_registry (), 
184     cspi_event_listener_get_corba (listener),
185     eventType, cspi_ev ());
186
187   return !cspi_exception ();
188 }
189
190 /**
191  * SPI_getDesktopCount:
192  *
193  * Get the number of virtual desktops.
194  * NOTE: currently multiple virtual desktops are not implemented, this
195  *       function always returns '1'.
196  *
197  * Returns: an integer indicating the number of active virtual desktops.
198  **/
199 int
200 SPI_getDesktopCount ()
201 {
202   int retval;
203
204   retval = Accessibility_Registry_getDesktopCount (
205     cspi_registry (), cspi_ev ());
206
207   cspi_return_val_if_ev ("getDesktopCount", -1);
208
209   return retval;
210 }
211
212 /**
213  * SPI_getDesktop:
214  * @i: an integer indicating which of the accessible desktops is to be returned.
215  *
216  * Get the virtual desktop indicated by index @i.
217  * NOTE: currently multiple virtual desktops are not implemented, this
218  *       function always returns '1'.
219  *
220  * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
221  **/
222 Accessible*
223 SPI_getDesktop (int i)
224 {
225   return cspi_object_add (
226     Accessibility_Registry_getDesktop (
227       cspi_registry (), i, cspi_ev ()));
228 }
229
230 /**
231  * SPI_getDesktopList:
232  * @desktop_list: a pointer to an array of #Accessible references.
233  *
234  * Get the list of virtual desktops.  On return, @list will point
235  *     to a newly-created, NULL terminated array of virtual desktop
236  *     pointers.
237  *     It is the responsibility of the caller to free this array when
238  *     it is no longer needed.
239  *
240  * Not Yet Implemented : this implementation always returns a single
241  * #Accessible desktop.
242  *
243  * Returns: an integer indicating how many virtual desktops have been
244  *          placed in the list pointed to by parameter @list.
245  **/
246 int
247 SPI_getDesktopList (Accessible ***desktop_list)
248 {
249   int i;
250   Accessible **list;
251   Accessibility_DesktopSeq *desktops;
252
253   if (!desktop_list)
254           return 0;
255
256   *desktop_list = NULL;
257
258   desktops = Accessibility_Registry_getDesktopList (cspi_registry (),
259                                                     cspi_ev ());
260
261   cspi_return_val_if_ev ("getDesktopList", 0);
262
263   list = g_new0 (Accessible *, desktops->_length + 1);
264
265   for (i = 0; i < desktops->_length; i++)
266     {
267       list [i] = cspi_object_add (
268               CORBA_Object_duplicate (desktops->_buffer [i], cspi_ev ()));
269     }
270   list [i] = NULL;
271
272   CORBA_free (desktops);
273
274   *desktop_list = list;
275
276   return i;
277 }
278
279 /**
280  * SPI_freeDesktopList:
281  * @desktop_list: a pointer to an array of #Accessible objects
282  * as returned from @SPI_getDesktopList
283  * 
284  * This routine frees the memory associated with the list.
285  **/
286 void
287 SPI_freeDesktopList (Accessible **desktop_list)
288 {
289   Accessible **p;
290   
291   for (p = desktop_list; p && *p; p++)
292     {
293       cspi_object_unref (*p);
294     }
295   g_free (desktop_list);
296 }
297
298 /**
299  * SPI_KEYSET_ALL_KEYS:
300  * @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
301  *                       includes all keycodes and keyvals for the specified modifier set.
302  **/
303
304 /**
305  * SPI_registerAccessibleKeystrokeListener:
306  * @listener:  a pointer to the #AccessibleKeystrokeListener for which
307  *             keystroke events are requested.
308  * @keys:      a pointer to the #AccessibleKeySet indicating which
309  *             keystroke events are requested, or #SPI_KEYSET_ALL_KEYS
310  *             to indicate that all keycodes and keyvals for the specified
311  *             modifier set are to be included.
312  * @modmask:   an #AccessibleKeyMaskType mask indicating which
313  *             key event modifiers must be set in combination with @keys,
314  *             events will only be reported for key events for which all
315  *             modifiers in @modmask are set.  If you wish to listen for
316  *             events with multiple modifier combinations you must call
317  *             registerAccessibleKeystrokeListener() once for each combination.
318  * @eventmask: an #AccessibleKeyMaskType mask indicating which
319  *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
320  * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
321  *             the behavior of the notification/listener transaction.
322  *             
323  * Register a listener for keystroke events, either pre-emptively for
324  *             all windows (SPI_KEYLISTENER_ALL_WINDOWS),
325  *             non-preemptively (SPI_KEYLISTENER_NOSYNC), or
326  *             pre-emptively at the toolkit level (SPI_KEYLISTENER_CANCONSUME).
327  *             If ALL_WINDOWS or CANCONSUME are used, the event is consumed
328  *             upon receipt if one of @listener's callbacks returns #TRUE.
329  *             ( Other sync_type values may be available in the future )
330  *
331  * Returns: #TRUE if successful, otherwise #FALSE.
332  **/
333 SPIBoolean
334 SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
335                                          AccessibleKeySet             *keys,
336                                          AccessibleKeyMaskType         modmask,
337                                          AccessibleKeyEventMask        eventmask,
338                                          AccessibleKeyListenerSyncType sync_type)
339 {
340   gint                                i;
341   Accessibility_KeySet                key_set;
342   Accessibility_KeyEventTypeSeq       key_events;
343   Accessibility_ControllerEventMask   controller_event_mask;
344   Accessibility_DeviceEventController device_event_controller;
345   Accessibility_EventListenerMode     listener_mode;
346   Accessibility_EventType             key_event_types [2];
347   SPIBoolean                          retval = FALSE;
348
349   if (!listener)
350     {
351       return retval;
352     }
353
354   device_event_controller = 
355     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
356
357   cspi_return_val_if_ev ("getting event controller", FALSE);
358
359   /* copy the keyval filter values from the C api into the CORBA KeySet */
360   if (keys)
361     {
362       key_set._length = keys->len;
363       key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
364       for (i = 0; i < key_set._length; ++i)
365         {
366           key_set._buffer[i].keycode = keys->keycodes[i];
367           key_set._buffer[i].keysym = keys->keysyms[i];
368           if (keys->keystrings && keys->keystrings[i]) 
369             {
370               key_set._buffer[i].keystring = CORBA_string_dup(keys->keystrings[i]);
371             } 
372           else 
373             {
374               key_set._buffer[i].keystring = CORBA_string_dup("");
375             }
376         }
377     }
378   else
379     {
380       key_set._length = 0;
381       key_set._buffer = NULL;
382     }
383         
384   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
385   i = 0;
386   key_events._buffer = key_event_types;
387   if (eventmask & SPI_KEY_PRESSED)
388     {
389       key_events._buffer[i++] = Accessibility_KEY_PRESSED_EVENT;
390     }
391   if (eventmask & SPI_KEY_RELEASED)
392     {
393       key_events._buffer[i++] = Accessibility_KEY_RELEASED_EVENT;
394     }
395   key_events._length = i;
396   
397   controller_event_mask = (CORBA_unsigned_long) modmask;
398
399   listener_mode.synchronous =
400           (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_SYNCHRONOUS)!=0);
401   listener_mode.preemptive =
402           (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_CANCONSUME)!=0);
403   listener_mode.global =
404           (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0);
405
406   retval = Accessibility_DeviceEventController_registerKeystrokeListener (
407     device_event_controller,
408     cspi_event_listener_get_corba (listener),
409     &key_set,
410     controller_event_mask,
411     &key_events,
412     &listener_mode,
413     cspi_ev ());
414
415   CORBA_free (key_set._buffer);
416
417   cspi_return_val_if_ev ("registering keystroke listener", FALSE);
418
419   cspi_release_unref (device_event_controller);
420
421   return retval;
422 }
423
424 /**
425  * SPI_deregisterAccessibleKeystrokeListener:
426  * @listener: a pointer to the #AccessibleKeystrokeListener for which
427  *            keystroke events are requested.
428  * @modmask:  the key modifier mask for which this listener is to be
429  *            'deregistered' (of type #AccessibleeyMaskType).
430  *
431  * Removes a keystroke event listener from the registry's listener queue,
432  *            ceasing notification of events with modifiers matching @modmask.
433  *
434  * Returns: #TRUE if successful, otherwise #FALSE.
435  **/
436 SPIBoolean
437 SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
438                                            AccessibleKeyMaskType        modmask)
439 {
440   Accessibility_ControllerEventMask   controller_event_mask;
441   Accessibility_KeySet                key_set;
442   Accessibility_KeyEventTypeSeq       key_events;
443   Accessibility_DeviceEventController device_event_controller;
444
445   if (!listener)
446     {
447       return FALSE;
448     }
449
450   device_event_controller = 
451     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
452
453   cspi_return_val_if_ev ("getting keystroke listener", FALSE);
454
455   controller_event_mask = (CORBA_unsigned_long) modmask;
456
457   key_events._buffer = NULL;
458   key_events._length = 0;
459
460   key_set._buffer = NULL;
461   key_set._length = 0;
462
463   Accessibility_DeviceEventController_deregisterKeystrokeListener (
464     device_event_controller,
465     cspi_event_listener_get_corba (listener),
466     &key_set,
467     controller_event_mask,
468     &key_events,
469     cspi_ev ());
470
471   cspi_release_unref (device_event_controller);
472
473   return TRUE;
474 }
475
476 /**
477  * SPI_registerDeviceEventListener:
478  * @listener:  a pointer to the #AccessibleDeviceListener which requests
479  *             the events.
480  * @eventmask: an #AccessibleDeviceEventMask mask indicating which
481  *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
482  * @filter: Unused parameter.
483  *             
484  * Register a listener for device events, for instance button events.
485  *
486  * Returns: #TRUE if successful, otherwise #FALSE.
487  **/
488 SPIBoolean
489 SPI_registerDeviceEventListener (AccessibleDeviceListener  *listener,
490                                  AccessibleDeviceEventMask  eventmask,
491                                  void                      *filter)
492 {
493   Accessibility_DeviceEventController device_event_controller;
494   SPIBoolean                          retval = FALSE;
495   Accessibility_EventTypeSeq          event_types;
496   Accessibility_EventType             event_type_buffer[2];
497   gint                                i;
498
499   if (!listener)
500     {
501       return retval;
502     }
503
504   device_event_controller = 
505     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
506
507   cspi_return_val_if_ev ("getting event controller", FALSE);
508
509   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
510   
511   event_types._buffer = event_type_buffer;
512   i = 0;
513
514   if (eventmask & SPI_BUTTON_PRESSED)
515     {
516       event_types._buffer[i++] = Accessibility_BUTTON_PRESSED_EVENT;
517     }
518   if (eventmask & SPI_BUTTON_RELEASED)
519     {
520       event_types._buffer[i++] = Accessibility_BUTTON_RELEASED_EVENT;
521     }
522
523   event_types._length = i;
524   
525   retval = Accessibility_DeviceEventController_registerDeviceEventListener (
526     device_event_controller,
527     cspi_event_listener_get_corba (listener),
528     &event_types,
529     cspi_ev ());
530
531   cspi_return_val_if_ev ("registering keystroke listener", FALSE);
532
533   cspi_release_unref (device_event_controller);
534
535   return retval;
536 }
537
538 /**
539  * SPI_deregisterDeviceEventListener:
540  * @listener: a pointer to the #AccessibleDeviceListener for which
541  *            device events are requested.
542  * @filter: Unused parameter.
543  *
544  * Removes a device event listener from the registry's listener queue,
545  *            ceasing notification of events of the specified type.
546  *
547  * Returns: #TRUE if successful, otherwise #FALSE.
548  **/
549 SPIBoolean
550 SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener,
551                                    void                     *filter)
552 {
553   Accessibility_DeviceEventController device_event_controller;
554   Accessibility_EventTypeSeq       event_types;
555   Accessibility_EventType          event_type_buff[2];
556
557   if (!listener)
558     {
559       return FALSE;
560     }
561
562   device_event_controller = 
563     Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
564
565   cspi_return_val_if_ev ("getting keystroke listener", FALSE);
566
567   event_types._buffer = event_type_buff;
568   event_types._length = 2;
569   event_types._buffer[0] = Accessibility_BUTTON_PRESSED_EVENT;
570   event_types._buffer[1] = Accessibility_BUTTON_RELEASED_EVENT;
571
572   Accessibility_DeviceEventController_deregisterDeviceEventListener (
573     device_event_controller,
574     cspi_event_listener_get_corba (listener),
575     &event_types,    
576     cspi_ev ());
577
578   cspi_release_unref (device_event_controller);
579
580   return TRUE;
581 }
582
583 /**
584  * SPI_generateKeyboardEvent:
585  * @keyval: a long integer indicating the keycode or keysym of the key event
586  *           being synthesized.
587  * @keystring: an (optional) UTF-8 string which, if @keyval is NULL,
588  *           indicates a 'composed' keyboard input string which is 
589  *           being synthesized; this type of keyboard event synthesis does
590  *           not emulate hardware keypresses but injects the string 
591  *           as though a composing input method (such as XIM) were used.
592  * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
593  *           is to be interpreted as a keysym rather than a keycode
594  *           (CSPI_KEYSYM), or whether to synthesize
595  *           SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
596  *
597  * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
598  * current UI context).
599  *
600  * Returns: #TRUE if successful, otherwise #FALSE.
601  **/
602 SPIBoolean
603 SPI_generateKeyboardEvent (long int keyval,
604                            char *keystring,
605                            AccessibleKeySynthType synth_type)
606 {
607   Accessibility_KeySynthType keysynth_type;
608   Accessibility_DeviceEventController device_event_controller = 
609           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
610
611   cspi_return_val_if_ev ("getting event controller for key event gen", FALSE);
612
613   switch (synth_type)
614     {
615       case SPI_KEY_PRESS:
616           keysynth_type = Accessibility_KEY_PRESS;
617           break;
618       case SPI_KEY_RELEASE:
619           keysynth_type = Accessibility_KEY_RELEASE;
620           break;
621       case SPI_KEY_PRESSRELEASE:
622           keysynth_type = Accessibility_KEY_PRESSRELEASE;
623           break;
624       case SPI_KEY_SYM:
625           keysynth_type = Accessibility_KEY_SYM;
626           break;
627       case SPI_KEY_STRING:
628           keysynth_type = Accessibility_KEY_STRING;
629           break;
630       default:
631           return FALSE;
632     }
633
634   Accessibility_DeviceEventController_generateKeyboardEvent (device_event_controller,
635                                                              keyval,
636                                                              keystring ? keystring : "",
637                                                              keysynth_type,
638                                                              cspi_ev ());
639
640   cspi_return_val_if_ev ("generating keyboard event", FALSE);
641
642   cspi_release_unref (device_event_controller);
643
644   return TRUE;
645 }
646
647 /**
648  * SPI_generateMouseEvent:
649  * @x: a #long indicating the screen x coordinate of the mouse event.
650  * @y: a #long indicating the screen y coordinate of the mouse event.
651  * @name: a string indicating which mouse event to be synthesized
652  *        (e.g. "b1p", "b1c", "b2r", "rel", "abs").
653  *
654  * Synthesize a mouse event at a specific screen coordinate.
655  * Most AT clients should use the #AccessibleAction interface when
656  * tempted to generate mouse events, rather than this method.
657  * Event names: b1p = button 1 press; b2r = button 2 release;
658  *              b3c = button 3 click; b2d = button 2 double-click;
659  *              abs = absolute motion; rel = relative motion.
660  *
661  * Returns: #TRUE if successful, otherwise #FALSE.
662  **/
663 SPIBoolean
664 SPI_generateMouseEvent (long x, long y, char *name)
665 {
666   Accessibility_DeviceEventController device_event_controller = 
667           Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
668
669   cspi_return_val_if_ev ("getting event controller for mouse event gen", FALSE);
670
671   Accessibility_DeviceEventController_generateMouseEvent (device_event_controller,
672                                                           x, y, name, cspi_ev ());
673   cspi_return_val_if_ev ("generating mouse event", FALSE);
674
675   cspi_release_unref (device_event_controller);
676
677   return TRUE;
678 }
679