source: trunk/third/at-spi/cspi/spi_registry.c @ 18688

Revision 18688, 20.7 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18687, which included commits to RCS files with non-trunk default branches.
Line 
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 **/
117SPIBoolean
118SPI_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 **/
146SPIBoolean
147SPI_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 **/
173SPIBoolean
174SPI_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 **/
199int
200SPI_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 **/
222Accessible*
223SPI_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 **/
246int
247SPI_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 **/
286void
287SPI_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 #CSPI_KEYSET_ALL_KEYS.
310 * @modmask:   an #AccessibleKeyMaskType mask indicating which
311 *             key event modifiers must be set in combination with @keys,
312 *             events will only be reported for key events for which all
313 *             modifiers in @modmask are set.  If you wish to listen for
314 *             events with multiple modifier combinations you must call
315 *             registerAccessibleKeystrokeListener() once for each combination.
316 * @eventmask: an #AccessibleKeyMaskType mask indicating which
317 *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
318 * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating
319 *             the behavior of the notification/listener transaction.
320 *             
321 * Register a listener for keystroke events, either pre-emptively for
322 *             all windows (CSPI_KEYLISTENER_ALL_WINDOWS), or
323 *             non-preemptively (CSPI_KEYLISTENER_NOSYNC).
324 *             ( Other sync_type values may be available in the future.)
325 *
326 * Returns: #TRUE if successful, otherwise #FALSE.
327 **/
328SPIBoolean
329SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
330                                         AccessibleKeySet             *keys,
331                                         AccessibleKeyMaskType         modmask,
332                                         AccessibleKeyEventMask        eventmask,
333                                         AccessibleKeyListenerSyncType sync_type)
334{
335  gint                                i;
336  Accessibility_KeySet                key_set;
337  Accessibility_KeyEventTypeSeq       key_events;
338  Accessibility_ControllerEventMask   controller_event_mask;
339  Accessibility_DeviceEventController device_event_controller;
340  Accessibility_EventListenerMode     listener_mode;
341  Accessibility_KeyEventType          key_event_types [2];
342  SPIBoolean                          retval = FALSE;
343
344  if (!listener)
345    {
346      return retval;
347    }
348
349  device_event_controller =
350    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
351
352  cspi_return_val_if_ev ("getting event controller", FALSE);
353
354  /* copy the keyval filter values from the C api into the CORBA KeySet */
355  if (keys)
356    {
357      key_set._length = keys->len;
358      key_set._buffer = Accessibility_KeySet_allocbuf (keys->len);
359      for (i = 0; i < key_set._length; ++i)
360        {
361          key_set._buffer[i].keycode = keys->keycodes[i];
362          key_set._buffer[i].keysym = keys->keysyms[i];
363          if (keys->keystrings && keys->keystrings[i])
364            {
365              key_set._buffer[i].keystring = CORBA_string_dup(keys->keystrings[i]);
366            }
367          else
368            {
369              key_set._buffer[i].keystring = CORBA_string_dup("");
370            }
371        }
372    }
373  else
374    {
375      key_set._length = 0;
376      key_set._buffer = NULL;
377    }
378       
379  /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
380  i = 0;
381  key_events._buffer = key_event_types;
382  if (eventmask & SPI_KEY_PRESSED)
383    {
384      key_events._buffer[i++] = Accessibility_KEY_PRESSED;
385    }
386  if (eventmask & SPI_KEY_RELEASED)
387    {
388      key_events._buffer[i++] = Accessibility_KEY_RELEASED;
389    }
390  key_events._length = i;
391 
392  controller_event_mask = (CORBA_unsigned_long) modmask;
393
394  listener_mode.synchronous =
395          (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_SYNCHRONOUS)!=0);
396  listener_mode.preemptive =
397          (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_CANCONSUME)!=0);
398  listener_mode.global =
399          (CORBA_boolean) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0);
400
401  retval = Accessibility_DeviceEventController_registerKeystrokeListener (
402    device_event_controller,
403    cspi_event_listener_get_corba (listener),
404    &key_set,
405    controller_event_mask,
406    &key_events,
407    &listener_mode,
408    cspi_ev ());
409
410  CORBA_free (key_set._buffer);
411
412  cspi_return_val_if_ev ("registering keystroke listener", FALSE);
413
414  cspi_release_unref (device_event_controller);
415
416  return retval;
417}
418
419/**
420 * SPI_deregisterAccessibleKeystrokeListener:
421 * @listener: a pointer to the #AccessibleKeystrokeListener for which
422 *            keystroke events are requested.
423 * @modmask:  the key modifier mask for which this listener is to be
424 *            'deregistered' (of type #AccessibleeyMaskType).
425 *
426 * Removes a keystroke event listener from the registry's listener queue,
427 *            ceasing notification of events with modifiers matching @modmask.
428 *
429 * Returns: #TRUE if successful, otherwise #FALSE.
430 **/
431SPIBoolean
432SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
433                                           AccessibleKeyMaskType        modmask)
434{
435  Accessibility_ControllerEventMask   controller_event_mask;
436  Accessibility_KeySet                key_set;
437  Accessibility_KeyEventTypeSeq       key_events;
438  Accessibility_DeviceEventController device_event_controller;
439
440  if (!listener)
441    {
442      return FALSE;
443    }
444
445  device_event_controller =
446    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
447
448  cspi_return_val_if_ev ("getting keystroke listener", FALSE);
449
450  controller_event_mask = (CORBA_unsigned_long) modmask;
451
452  key_events._buffer = NULL;
453  key_events._length = 0;
454
455  key_set._buffer = NULL;
456  key_set._length = 0;
457
458  Accessibility_DeviceEventController_deregisterKeystrokeListener (
459    device_event_controller,
460    cspi_event_listener_get_corba (listener),
461    &key_set,
462    controller_event_mask,
463    &key_events,
464    cspi_ev ());
465
466  cspi_release_unref (device_event_controller);
467
468  return TRUE;
469}
470
471/**
472 * SPI_registerDeviceEventListener:
473 * @listener:  a pointer to the #AccessibleDeviceListener which requests
474 *             the events.
475 * @eventmask: an #AccessibleDeviceEventMask mask indicating which
476 *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
477 *             
478 * Register a listener for device events, for instance button events.
479 *
480 * Returns: #TRUE if successful, otherwise #FALSE.
481 **/
482SPIBoolean
483SPI_registerDeviceEventListener (AccessibleDeviceListener  *listener,
484                                 AccessibleDeviceEventMask  eventmask,
485                                 void                      *filter)
486{
487  Accessibility_DeviceEventController device_event_controller;
488  SPIBoolean                          retval = FALSE;
489  Accessibility_EventTypeSeq          event_types;
490  Accessibility_EventType             event_type_buffer[2];
491  gint                                i;
492
493  if (!listener)
494    {
495      return retval;
496    }
497
498  device_event_controller =
499    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
500
501  cspi_return_val_if_ev ("getting event controller", FALSE);
502
503  /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
504 
505  event_types._buffer = event_type_buffer;
506  i = 0;
507
508  if (eventmask & SPI_BUTTON_PRESSED)
509    {
510      event_types._buffer[i++] = Accessibility_BUTTON_PRESSED_EVENT;
511    }
512  if (eventmask & SPI_BUTTON_RELEASED)
513    {
514      event_types._buffer[i++] = Accessibility_BUTTON_RELEASED_EVENT;
515    }
516
517  event_types._length = i;
518 
519  retval = Accessibility_DeviceEventController_registerDeviceEventListener (
520    device_event_controller,
521    cspi_event_listener_get_corba (listener),
522    &event_types,
523    cspi_ev ());
524
525  cspi_return_val_if_ev ("registering keystroke listener", FALSE);
526
527  cspi_release_unref (device_event_controller);
528
529  return retval;
530}
531
532/**
533 * SPI_deregisterDeviceEventListener:
534 * @listener: a pointer to the #AccessibleDeviceListener for which
535 *            device events are requested.
536 *
537 * Removes a device event listener from the registry's listener queue,
538 *            ceasing notification of events of the specified type.
539 *
540 * Returns: #TRUE if successful, otherwise #FALSE.
541 **/
542SPIBoolean
543SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener,
544                                   void                     *filter)
545{
546  Accessibility_DeviceEventController device_event_controller;
547  Accessibility_EventTypeSeq       event_types;
548  Accessibility_EventType          event_type_buff[2];
549
550  if (!listener)
551    {
552      return FALSE;
553    }
554
555  device_event_controller =
556    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
557
558  cspi_return_val_if_ev ("getting keystroke listener", FALSE);
559
560  event_types._buffer = event_type_buff;
561  event_types._length = 2;
562  event_types._buffer[0] = Accessibility_BUTTON_PRESSED_EVENT;
563  event_types._buffer[1] = Accessibility_BUTTON_RELEASED_EVENT;
564
565  Accessibility_DeviceEventController_deregisterDeviceEventListener (
566    device_event_controller,
567    cspi_event_listener_get_corba (listener),
568    &event_types,   
569    cspi_ev ());
570
571  cspi_release_unref (device_event_controller);
572
573  return TRUE;
574}
575
576/**
577 * SPI_generateKeyboardEvent:
578 * @keyval: a long integer indicating the keycode or keysym of the key event
579 *           being synthesized.
580 * @keystring: an (optional) UTF-8 string which, if @keyval is NULL,
581 *           indicates a 'composed' keyboard input string which is
582 *           being synthesized; this type of keyboard event synthesis does
583 *           not emulate hardware keypresses but injects the string
584 *           as though a composing input method (such as XIM) were used.
585 * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval
586 *           is to be interpreted as a keysym rather than a keycode
587 *           (CSPI_KEYSYM), or whether to synthesize
588 *           SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE).
589 *
590 * Synthesize a keyboard event (as if a hardware keyboard event occurred in the
591 * current UI context).
592 *
593 * Returns: #TRUE if successful, otherwise #FALSE.
594 **/
595SPIBoolean
596SPI_generateKeyboardEvent (long int keyval,
597                           char *keystring,
598                           AccessibleKeySynthType synth_type)
599{
600/* TODO: check current modifier status and
601 *  send keycode to alter, if necessary
602 */
603       
604  /* TODO: implement keystring use case */
605  Accessibility_KeySynthType keysynth_type;
606  Accessibility_DeviceEventController device_event_controller =
607          Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
608
609  cspi_return_val_if_ev ("getting event controller for key event gen", FALSE);
610
611  switch (synth_type)
612    {
613      case SPI_KEY_PRESS:
614          keysynth_type = Accessibility_KEY_PRESS;
615          break;
616      case SPI_KEY_RELEASE:
617          keysynth_type = Accessibility_KEY_RELEASE;
618          break;
619      case SPI_KEY_PRESSRELEASE:
620          keysynth_type = Accessibility_KEY_PRESSRELEASE;
621          break;
622      case SPI_KEY_SYM:
623          keysynth_type = Accessibility_KEY_SYM;
624          break;
625      case SPI_KEY_STRING:
626          keysynth_type = Accessibility_KEY_STRING;
627          break;
628      default:
629          return FALSE;
630    }
631
632  Accessibility_DeviceEventController_generateKeyboardEvent (device_event_controller,
633                                                             keyval,
634                                                             "",
635                                                             keysynth_type,
636                                                             cspi_ev ());
637
638  cspi_return_val_if_ev ("generating keyboard event", FALSE);
639
640  cspi_release_unref (device_event_controller);
641
642  return TRUE;
643}
644
645/**
646 * SPI_generateMouseEvent:
647 * @x: a #long indicating the screen x coordinate of the mouse event.
648 * @y: a #long indicating the screen y coordinate of the mouse event.
649 * @name: a string indicating which mouse event to be synthesized
650 *        (e.g. "b1p", "b1c", "b2r", "rel", "abs").
651 *
652 * Synthesize a mouse event at a specific screen coordinate.
653 * Most AT clients should use the #AccessibleAction interface when
654 * tempted to generate mouse events, rather than this method.
655 * Event names: b1p = button 1 press; b2r = button 2 release;
656 *              b3c = button 3 click; b2d = button 2 double-click;
657 *              abs = absolute motion; rel = relative motion.
658 *
659 * Returns: #TRUE if successful, otherwise #FALSE.
660 **/
661SPIBoolean
662SPI_generateMouseEvent (long x, long y, char *name)
663{
664  Accessibility_DeviceEventController device_event_controller =
665          Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
666
667  cspi_return_val_if_ev ("getting event controller for mouse event gen", FALSE);
668
669  Accessibility_DeviceEventController_generateMouseEvent (device_event_controller,
670                                                          x, y, name, cspi_ev ());
671  cspi_return_val_if_ev ("generating mouse event", FALSE);
672
673  cspi_release_unref (device_event_controller);
674
675  return TRUE;
676}
677
Note: See TracBrowser for help on using the repository browser.