2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001 Sun Microsystems Inc.
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.
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.
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.
23 /* spi_registry.c: Global functions wrapping the registry */
25 #include <cspi/spi-private.h>
28 * SPI_registerGlobalEventListener:
29 * @listener: the #AccessibleEventListener to be registered against an
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".
39 * Legal object event types:
41 * (property change events)
43 * object:property-change
44 * object:property-change:accessible-name
45 * object:property-change:accessible-description
46 * object:property-change:accessible-parent
47 * object:property-change:accessible-value
48 * object:property-change:accessible-role
49 * object:property-change:accessible-table-caption
50 * object:property-change:accessible-table-column-description
51 * object:property-change:accessible-table-column-header
52 * object:property-change:accessible-table-row-description
53 * object:property-change:accessible-table-row-header
54 * object:property-change:accessible-table-summary
56 * (other object events)
58 * object:state-changed
59 * object:children-changed
60 * object:visible-data-changed
61 * object:selection-changed
62 * object:text-selection-changed
64 * object:text-caret-moved
66 * object:row-reordered
68 * object:column-inserted
69 * object:column-reordered
70 * object:column-deleted
71 * object:model-changed
81 * window:desktop-create
82 * window:desktop-destroy
105 * NOTE: this string may be UTF-8, but should not contain byte value 56
106 * (ascii ':'), except as a delimiter, since non-UTF-8 string
107 * delimiting functions are used internally.
108 * In general, listening to
109 * toolkit-specific events is not recommended.
111 * Add an in-process callback function to an existing AccessibleEventListener.
113 * Returns: #TRUE if successful, otherwise #FALSE.
116 SPI_registerGlobalEventListener (AccessibleEventListener *listener,
117 const char *eventType)
124 Accessibility_Registry_registerGlobalEventListener (
126 cspi_event_listener_get_corba (listener),
127 eventType, cspi_ev ());
129 return !cspi_exception ();
133 * SPI_deregisterGlobalEventListenerAll:
134 * @listener: the #AccessibleEventListener to be registered against
137 * deregisters an AccessibleEventListener from the registry, for all
138 * event types it may be listening to. Use
139 * AccessibleEventListener_unref to release the
140 * listener reference.
142 * Returns: #TRUE if successful, otherwise #FALSE.
145 SPI_deregisterGlobalEventListenerAll (AccessibleEventListener *listener)
152 Accessibility_Registry_deregisterGlobalEventListenerAll (
154 cspi_event_listener_get_corba (listener),
157 return !cspi_exception ();
161 * SPI_deregisterGlobalEventListener:
162 * @listener: the #AccessibleEventListener registered against an event type.
163 * @eventType: a string specifying the event type for which this
164 * listener is to be deregistered.
166 * deregisters an AccessibleEventListener from the registry, for a specific
169 * Returns: #TRUE if successful, otherwise #FALSE.
172 SPI_deregisterGlobalEventListener (AccessibleEventListener *listener,
173 const char *eventType)
180 Accessibility_Registry_deregisterGlobalEventListener (
182 cspi_event_listener_get_corba (listener),
183 eventType, cspi_ev ());
185 return !cspi_exception ();
189 * SPI_getDesktopCount:
191 * Get the number of virtual desktops.
192 * NOTE: currently multiple virtual desktops are not implemented, this
193 * function always returns '1'.
195 * Returns: an integer indicating the number of active virtual desktops.
198 SPI_getDesktopCount ()
202 retval = Accessibility_Registry_getDesktopCount (
203 cspi_registry (), cspi_ev ());
205 cspi_return_val_if_ev ("getDesktopCount", -1);
212 * @i: an integer indicating which of the accessible desktops is to be returned.
214 * Get the virtual desktop indicated by index @i.
215 * NOTE: currently multiple virtual desktops are not implemented, this
216 * function always returns '1'.
218 * Returns: a pointer to the 'i-th' virtual desktop's #Accessible representation.
221 SPI_getDesktop (int i)
223 return cspi_object_add (
224 Accessibility_Registry_getDesktop (
225 cspi_registry (), i, cspi_ev ()));
229 * SPI_getDesktopList:
230 * @desktop_list: a pointer to an array of #Accessible references.
232 * Get the list of virtual desktops. On return, @list will point
233 * to a newly-created, NULL terminated array of virtual desktop
235 * It is the responsibility of the caller to free this array when
236 * it is no longer needed.
238 * Not Yet Implemented : this implementation always returns a single
239 * #Accessible desktop.
241 * Returns: an integer indicating how many virtual desktops have been
242 * placed in the list pointed to by parameter @list.
245 SPI_getDesktopList (Accessible ***desktop_list)
249 Accessibility_DesktopSeq *desktops;
254 *desktop_list = NULL;
256 desktops = Accessibility_Registry_getDesktopList (cspi_registry (),
259 cspi_return_val_if_ev ("getDesktopList", 0);
261 list = g_new0 (Accessible *, desktops->_length + 1);
263 for (i = 0; i < desktops->_length; i++)
265 list [i] = cspi_object_add (
266 CORBA_Object_duplicate (desktops->_buffer [i], cspi_ev ()));
270 CORBA_free (desktops);
272 *desktop_list = list;
278 * SPI_freeDesktopList:
279 * @desktop_list: a pointer to an array of #Accessible objects
280 * as returned from @SPI_getDesktopList
282 * This routine frees the memory associated with the list.
285 SPI_freeDesktopList (Accessible **desktop_list)
289 for (p = desktop_list; p && *p; p++)
291 cspi_object_unref (*p);
293 g_free (desktop_list);
297 * SPI_KEYSET_ALL_KEYS:
298 * @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
299 * includes all keycodes and keyvals for the specified modifier set.
303 * SPI_registerAccessibleKeystrokeListener:
304 * @listener: a pointer to the #AccessibleKeystrokeListener for which
305 * keystroke events are requested.
306 * @keys: a pointer to the #AccessibleKeySet indicating which
307 * keystroke events are requested, or #CSPI_KEYSET_ALL_KEYS.
308 * @modmask: an #AccessibleKeyMaskType mask indicating which
309 * key event modifiers must be set in combination with @keys,
310 * events will only be reported for key events for which all
311 * modifiers in @modmask are set. If you wish to listen for
312 * events with multiple modifier combinations you must call
313 * registerAccessibleKeystrokeListener() once for each combination.
314 * @eventmask: an #AccessibleKeyMaskType mask indicating which
315 * types of key events are requested (#SPI_KEY_PRESSED, etc.).
316 * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
317 * the behavior of the notification/listener transaction.
319 * Register a listener for keystroke events, either pre-emptively for
320 * all windows (CSPI_KEYLISTENER_ALL_WINDOWS), or
321 * non-preemptively (CSPI_KEYLISTENER_NOSYNC).
322 * ( Other sync_type values may be available in the future.)
324 * Returns: #TRUE if successful, otherwise #FALSE.
327 SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
328 AccessibleKeySet *keys,
329 AccessibleKeyMaskType modmask,
330 AccessibleKeyEventMask eventmask,
331 AccessibleKeyListenerSyncType sync_type)
334 Accessibility_KeySet key_set;
335 Accessibility_KeyEventTypeSeq key_events;
336 Accessibility_ControllerEventMask controller_event_mask;
337 Accessibility_DeviceEventController device_event_controller;
338 Accessibility_EventListenerMode listener_mode;
339 SPIBoolean retval = FALSE;
346 device_event_controller =
347 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
349 cspi_return_val_if_ev ("getting event controller", FALSE);
351 /* copy the keyval filter values from the C api into the CORBA KeySet */
354 key_set._length = keys->len;
355 key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
356 for (i = 0; i < key_set._length; ++i)
358 key_set._buffer[i].keycode = keys->keycodes[i];
359 key_set._buffer[i].keysym = keys->keysyms[i];
360 if (keys->keystrings && keys->keystrings[i])
362 key_set._buffer[i].keystring = keys->keystrings[i];
366 key_set._buffer[i].keystring = CORBA_string_dup("");
373 key_set._buffer = NULL;
376 /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
381 if (mask & eventmask)
387 while (mask & 0xFFFF);
389 key_events._buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
391 if (eventmask & SPI_KEY_PRESSED)
393 key_events._buffer[i++] = Accessibility_KEY_PRESSED;
395 if (eventmask & SPI_KEY_RELEASED)
397 key_events._buffer[i++] = Accessibility_KEY_RELEASED;
399 key_events._length = i;
401 controller_event_mask = (CORBA_unsigned_long) modmask;
403 listener_mode.synchronous =
404 (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_SYNCHRONOUS)!=0);
405 listener_mode.preemptive =
406 (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_CANCONSUME)!=0);
407 listener_mode.global =
408 (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0);
410 retval = Accessibility_DeviceEventController_registerKeystrokeListener (
411 device_event_controller,
412 cspi_event_listener_get_corba (listener),
414 controller_event_mask,
419 cspi_return_val_if_ev ("registering keystroke listener", FALSE);
421 cspi_release_unref (device_event_controller);
427 * SPI_deregisterAccessibleKeystrokeListener:
428 * @listener: a pointer to the #AccessibleKeystrokeListener for which
429 * keystroke events are requested.
430 * @modmask: the key modifier mask for which this listener is to be
431 * 'deregistered' (of type #AccessibleeyMaskType).
433 * Removes a keystroke event listener from the registry's listener queue,
434 * ceasing notification of events with modifiers matching @modmask.
436 * Returns: #TRUE if successful, otherwise #FALSE.
439 SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
440 AccessibleKeyMaskType modmask)
442 Accessibility_ControllerEventMask controller_event_mask;
443 Accessibility_KeySet key_set;
444 Accessibility_KeyEventTypeSeq key_events;
445 Accessibility_DeviceEventController device_event_controller;
452 device_event_controller =
453 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
455 cspi_return_val_if_ev ("getting keystroke listener", FALSE);
457 controller_event_mask = (CORBA_unsigned_long) modmask;
459 key_events._buffer = NULL;
460 key_events._length = 0;
462 key_set._buffer = NULL;
465 Accessibility_DeviceEventController_deregisterKeystrokeListener (
466 device_event_controller,
467 cspi_event_listener_get_corba (listener),
469 controller_event_mask,
473 cspi_release_unref (device_event_controller);
479 * SPI_generateKeyboardEvent:
480 * @keyval: a long integer indicating the keycode or keysym of the key event
482 * @keystring: an (optional) UTF-8 string which, if @keyval is NULL,
483 * indicates a 'composed' keyboard input string which is
484 * being synthesized; this type of keyboard event synthesis does
485 * not emulate hardware keypresses but injects the string
486 * as though a composing input method (such as XIM) were used.
487 * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
488 * is to be interpreted as a keysym rather than a keycode
489 * (CSPI_KEYSYM), or whether to synthesize
490 * SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
492 * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
493 * current UI context).
495 * Returns: #TRUE if successful, otherwise #FALSE.
498 SPI_generateKeyboardEvent (long int keyval,
500 AccessibleKeySynthType synth_type)
502 /* TODO: check current modifier status and
503 * send keycode to alter, if necessary
506 /* TODO: implement keystring use case */
507 Accessibility_KeySynthType keysynth_type;
508 Accessibility_DeviceEventController device_event_controller =
509 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
511 cspi_return_val_if_ev ("getting event controller for key event gen", FALSE);
516 keysynth_type = Accessibility_KEY_PRESS;
518 case SPI_KEY_RELEASE:
519 keysynth_type = Accessibility_KEY_RELEASE;
521 case SPI_KEY_PRESSRELEASE:
522 keysynth_type = Accessibility_KEY_PRESSRELEASE;
525 keysynth_type = Accessibility_KEY_SYM;
528 keysynth_type = Accessibility_KEY_STRING;
534 Accessibility_DeviceEventController_generateKeyboardEvent (device_event_controller,
540 cspi_return_val_if_ev ("generating keyboard event", FALSE);
542 cspi_release_unref (device_event_controller);
548 * SPI_generateMouseEvent:
549 * @x: a #long indicating the screen x coordinate of the mouse event.
550 * @y: a #long indicating the screen y coordinate of the mouse event.
551 * @name: a string indicating which mouse event to be synthesized
552 * (e.g. "b1p", "b1c", "b2r", "rel", "abs").
554 * Synthesize a mouse event at a specific screen coordinate.
555 * Most AT clients should use the #AccessibleAction interface when
556 * tempted to generate mouse events, rather than this method.
557 * Event names: b1p = button 1 press; b2r = button 2 release;
558 * b3c = button 3 click; b2d = button 2 double-click;
559 * abs = absolute motion; rel = relative motion.
561 * Returns: #TRUE if successful, otherwise #FALSE.
564 SPI_generateMouseEvent (long x, long y, char *name)
566 Accessibility_DeviceEventController device_event_controller =
567 Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
569 cspi_return_val_if_ev ("getting event controller for mouse event gen", FALSE);
571 Accessibility_DeviceEventController_generateMouseEvent (device_event_controller,
572 x, y, name, cspi_ev ());
573 cspi_return_val_if_ev ("generating mouse event", FALSE);
575 cspi_release_unref (device_event_controller);