2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001, 2002 Sun Microsystems Inc.,
6 * Copyright 2001, 2002 Ximian, Inc.
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.
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.
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.
24 /* spi_registry.c: Global functions wrapping the registry */
26 #include <cspi/spi-private.h>
29 * SPI_registerGlobalEventListener:
30 * @listener: the #AccessibleEventListener to be registered against an
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".
40 * Legal object event types:
42 * (property change events)
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
57 * (other object events)
59 * object:state-changed
60 * object:children-changed
61 * object:visible-data-changed
62 * object:selection-changed
63 * object:text-selection-changed
65 * object:text-caret-moved
67 * object:row-reordered
69 * object:column-inserted
70 * object:column-reordered
71 * object:column-deleted
72 * object:model-changed
73 * object:active-descendant-changed
83 * window:desktop-create
84 * window:desktop-destroy
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.
113 * Add an in-process callback function to an existing AccessibleEventListener.
115 * Returns: #TRUE if successful, otherwise #FALSE.
118 SPI_registerGlobalEventListener (AccessibleEventListener *listener,
119 const char *eventType)
126 Accessibility_Registry_registerGlobalEventListener (
128 cspi_event_listener_get_corba (listener),
129 eventType, cspi_ev ());
131 return !cspi_exception ();
135 * SPI_deregisterGlobalEventListenerAll:
136 * @listener: the #AccessibleEventListener to be registered against
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.
144 * Returns: #TRUE if successful, otherwise #FALSE.
147 SPI_deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
154 Accessibility_Registry_deregisterGlobalEventListenerAll (
156 cspi_event_listener_get_corba (listener),
159 return !cspi_exception ();
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.
168 * deregisters an AccessibleEventListener from the registry, for a specific
171 * Returns: #TRUE if successful, otherwise #FALSE.
174 SPI_deregisterGlobalEventListener (AccessibleEventListener *listener,
175 const char *eventType)
182 Accessibility_Registry_deregisterGlobalEventListener (
184 cspi_event_listener_get_corba (listener),
185 eventType, cspi_ev ());
187 return !cspi_exception ();
191 * SPI_getDesktopCount:
193 * Get the number of virtual desktops.
194 * NOTE: currently multiple virtual desktops are not implemented, this
195 * function always returns '1'.
197 * Returns: an integer indicating the number of active virtual desktops.
200 SPI_getDesktopCount ()
204 retval = Accessibility_Registry_getDesktopCount (
205 cspi_registry (), cspi_ev ());
207 cspi_return_val_if_ev ("getDesktopCount", -1);
214 * @i: an integer indicating which of the accessible desktops is to be returned.
216 * Get the virtual desktop indicated by index @i.
217 * NOTE: currently multiple virtual desktops are not implemented, this
218 * function always returns '1'.
220 * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
223 SPI_getDesktop (int i)
225 return cspi_object_add (
226 Accessibility_Registry_getDesktop (
227 cspi_registry (), i, cspi_ev ()));
231 * SPI_getDesktopList:
232 * @desktop_list: a pointer to an array of #Accessible references.
234 * Get the list of virtual desktops. On return, @list will point
235 * to a newly-created, NULL terminated array of virtual desktop
237 * It is the responsibility of the caller to free this array when
238 * it is no longer needed.
240 * Not Yet Implemented : this implementation always returns a single
241 * #Accessible desktop.
243 * Returns: an integer indicating how many virtual desktops have been
244 * placed in the list pointed to by parameter @list.
247 SPI_getDesktopList (Accessible ***desktop_list)
251 Accessibility_DesktopSeq *desktops;
256 *desktop_list = NULL;
258 desktops = Accessibility_Registry_getDesktopList (cspi_registry (),
261 cspi_return_val_if_ev ("getDesktopList", 0);
263 list = g_new0 (Accessible *, desktops->_length + 1);
265 for (i = 0; i < desktops->_length; i++)
267 list [i] = cspi_object_add (
268 CORBA_Object_duplicate (desktops->_buffer [i], cspi_ev ()));
272 CORBA_free (desktops);
274 *desktop_list = list;
280 * SPI_freeDesktopList:
281 * @desktop_list: a pointer to an array of #Accessible objects
282 * as returned from @SPI_getDesktopList
284 * This routine frees the memory associated with the list.
287 SPI_freeDesktopList (Accessible **desktop_list)
291 for (p = desktop_list; p && *p; p++)
293 cspi_object_unref (*p);
295 g_free (desktop_list);
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.
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.
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 )
331 * Returns: #TRUE if successful, otherwise #FALSE.
334 SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
335 AccessibleKeySet *keys,
336 AccessibleKeyMaskType modmask,
337 AccessibleKeyEventMask eventmask,
338 AccessibleKeyListenerSyncType sync_type)
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;
354 device_event_controller =
355 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
357 cspi_return_val_if_ev ("getting event controller", FALSE);
359 /* copy the keyval filter values from the C api into the CORBA KeySet */
362 key_set._length = keys->len;
363 key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
364 for (i = 0; i < key_set._length; ++i)
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])
370 key_set._buffer[i].keystring = CORBA_string_dup(keys->keystrings[i]);
374 key_set._buffer[i].keystring = CORBA_string_dup("");
381 key_set._buffer = NULL;
384 /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
386 key_events._buffer = key_event_types;
387 if (eventmask & SPI_KEY_PRESSED)
389 key_events._buffer[i++] = Accessibility_KEY_PRESSED_EVENT;
391 if (eventmask & SPI_KEY_RELEASED)
393 key_events._buffer[i++] = Accessibility_KEY_RELEASED_EVENT;
395 key_events._length = i;
397 controller_event_mask = (CORBA_unsigned_long) modmask;
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);
406 retval = Accessibility_DeviceEventController_registerKeystrokeListener (
407 device_event_controller,
408 cspi_event_listener_get_corba (listener),
410 controller_event_mask,
415 CORBA_free (key_set._buffer);
417 cspi_return_val_if_ev ("registering keystroke listener", FALSE);
419 cspi_release_unref (device_event_controller);
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).
431 * Removes a keystroke event listener from the registry's listener queue,
432 * ceasing notification of events with modifiers matching @modmask.
434 * Returns: #TRUE if successful, otherwise #FALSE.
437 SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
438 AccessibleKeyMaskType modmask)
440 Accessibility_ControllerEventMask controller_event_mask;
441 Accessibility_KeySet key_set;
442 Accessibility_KeyEventTypeSeq key_events;
443 Accessibility_DeviceEventController device_event_controller;
450 device_event_controller =
451 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
453 cspi_return_val_if_ev ("getting keystroke listener", FALSE);
455 controller_event_mask = (CORBA_unsigned_long) modmask;
457 key_events._buffer = NULL;
458 key_events._length = 0;
460 key_set._buffer = NULL;
463 Accessibility_DeviceEventController_deregisterKeystrokeListener (
464 device_event_controller,
465 cspi_event_listener_get_corba (listener),
467 controller_event_mask,
471 cspi_release_unref (device_event_controller);
477 * SPI_registerDeviceEventListener:
478 * @listener: a pointer to the #AccessibleDeviceListener which requests
480 * @eventmask: an #AccessibleDeviceEventMask mask indicating which
481 * types of key events are requested (#SPI_KEY_PRESSED, etc.).
482 * @filter: Unused parameter.
484 * Register a listener for device events, for instance button events.
486 * Returns: #TRUE if successful, otherwise #FALSE.
489 SPI_registerDeviceEventListener (AccessibleDeviceListener *listener,
490 AccessibleDeviceEventMask eventmask,
493 Accessibility_DeviceEventController device_event_controller;
494 SPIBoolean retval = FALSE;
495 Accessibility_EventTypeSeq event_types;
496 Accessibility_EventType event_type_buffer[2];
504 device_event_controller =
505 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
507 cspi_return_val_if_ev ("getting event controller", FALSE);
509 /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
511 event_types._buffer = event_type_buffer;
514 if (eventmask & SPI_BUTTON_PRESSED)
516 event_types._buffer[i++] = Accessibility_BUTTON_PRESSED_EVENT;
518 if (eventmask & SPI_BUTTON_RELEASED)
520 event_types._buffer[i++] = Accessibility_BUTTON_RELEASED_EVENT;
523 event_types._length = i;
525 retval = Accessibility_DeviceEventController_registerDeviceEventListener (
526 device_event_controller,
527 cspi_event_listener_get_corba (listener),
531 cspi_return_val_if_ev ("registering keystroke listener", FALSE);
533 cspi_release_unref (device_event_controller);
539 * SPI_deregisterDeviceEventListener:
540 * @listener: a pointer to the #AccessibleDeviceListener for which
541 * device events are requested.
542 * @filter: Unused parameter.
544 * Removes a device event listener from the registry's listener queue,
545 * ceasing notification of events of the specified type.
547 * Returns: #TRUE if successful, otherwise #FALSE.
550 SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener,
553 Accessibility_DeviceEventController device_event_controller;
554 Accessibility_EventTypeSeq event_types;
555 Accessibility_EventType event_type_buff[2];
562 device_event_controller =
563 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
565 cspi_return_val_if_ev ("getting keystroke listener", FALSE);
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;
572 Accessibility_DeviceEventController_deregisterDeviceEventListener (
573 device_event_controller,
574 cspi_event_listener_get_corba (listener),
578 cspi_release_unref (device_event_controller);
584 * SPI_generateKeyboardEvent:
585 * @keyval: a long integer indicating the keycode or keysym of the key event
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).
597 * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
598 * current UI context).
600 * Returns: #TRUE if successful, otherwise #FALSE.
603 SPI_generateKeyboardEvent (long int keyval,
605 AccessibleKeySynthType synth_type)
607 Accessibility_KeySynthType keysynth_type;
608 Accessibility_DeviceEventController device_event_controller =
609 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
611 cspi_return_val_if_ev ("getting event controller for key event gen", FALSE);
616 keysynth_type = Accessibility_KEY_PRESS;
618 case SPI_KEY_RELEASE:
619 keysynth_type = Accessibility_KEY_RELEASE;
621 case SPI_KEY_PRESSRELEASE:
622 keysynth_type = Accessibility_KEY_PRESSRELEASE;
625 keysynth_type = Accessibility_KEY_SYM;
628 keysynth_type = Accessibility_KEY_STRING;
634 Accessibility_DeviceEventController_generateKeyboardEvent (device_event_controller,
636 keystring ? keystring : "",
640 cspi_return_val_if_ev ("generating keyboard event", FALSE);
642 cspi_release_unref (device_event_controller);
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").
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.
661 * Returns: #TRUE if successful, otherwise #FALSE.
664 SPI_generateMouseEvent (long x, long y, char *name)
666 Accessibility_DeviceEventController device_event_controller =
667 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
669 cspi_return_val_if_ev ("getting event controller for mouse event gen", FALSE);
671 Accessibility_DeviceEventController_generateMouseEvent (device_event_controller,
672 x, y, name, cspi_ev ());
673 cspi_return_val_if_ev ("generating mouse event", FALSE);
675 cspi_release_unref (device_event_controller);