Fix for 95827, adds API for registering "AccessibleDeviceListeners"
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 17 Nov 2002 13:54:00 +0000 (13:54 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 17 Nov 2002 13:54:00 +0000 (13:54 +0000)
which can receive (and potentially, consume) device events such as
mouse button events, etc.  Necessary for GOK and other assistive
technologies.
Added a couple of slots to epvs in IDL, so this breaks internal bincompat.
CSPI bincompat not affected.

git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@360 e2bd861d-eb25-0410-b326-f6ed22b6b98c

33 files changed:
ChangeLog
configure.in
cspi/bonobo/cspi-bonobo-listener.c
cspi/bonobo/cspi-bonobo-listener.h
cspi/spi-impl.h
cspi/spi-listener.h
cspi/spi.h
cspi/spi_action.c
cspi/spi_event.c
cspi/spi_registry.c
cspi/spi_text.c
docs/reference/cspi/tmpl/spi_registry.sgml
idl/Accessibility_Accessible.idl
idl/Accessibility_Application.idl
idl/Accessibility_Desktop.idl
idl/Accessibility_Event.idl
idl/Accessibility_Hypertext.idl
idl/Accessibility_Registry.idl
libspi/Makefile.am
libspi/devicelistener.c [new file with mode: 0644]
libspi/devicelistener.h [new file with mode: 0644]
libspi/keystrokelistener.h
libspi/libspi.h
libspi/text.c
registryd/deviceeventcontroller.c
registryd/deviceeventcontroller.h
registryd/registry.c
test/Makefile.am
test/event-listener-test.c
test/key-listener-test.c
test/keysynth-demo.c
test/test-simple.c
test/visual-bell.c

index c294176..9725c93 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,210 @@
+2002-11-17  Bill Haneman <bill.haneman@sun.com>
+
+       * configure.in:
+       Revved to 1.1.3, interface-age=3, binary-age=3.
+       Added REBUILD macro.
+
+       * test/Makefile.am:
+       Removed accessx-gui from the tests, since we have a nice
+       keyboard accessibility capplet now :-)
+
+       * test/keysynth-demo.c:
+       (increment_scan): removed do-nothing default: case,
+       silences warning.
+
+       * test/visual-bell.c:
+       (main) : removed do-nothing default: case, 
+       silences warning.
+
+       * cspi/spi_action.c:
+       (AccessibleAction_getKeyBinding_): 
+       Documented keybinding string format.
+       FIX for bug 97916.
+
+       * cspi/spi_text.c:
+       (AccessibleText_getAttributes):
+       Documented the text attribute string format.
+       It's changed to use semicolon delimiters also,
+       to prevent clashes with CSS attributes, but the old
+       trick of looking for ", " strings will still work
+       (as unreliably as ever).  Fix for bug related to 97916.
+
+       * cspi/spi_event.c:
+       Include <cspi/bonobo/cspi-bonobo-listener.h>
+       Fixes build warning.
+       (SPI_freeAccessibleKeySet):
+       (AccessibleKeystrokeListener_addCallback):
+       (AccessibleKeystrokeListener_removeCallback):
+       Modify to use AccessibleDeviceListener API internally,
+       instead of AccessibleKeystrokeListener.
+       
+       * idl/Accessibility_Event.idl:
+       Added two more empty slots to EventListener (for a total of four).
+
+       * idl/Accessibility_Accessible.idl:
+       Added four empty slots to Accessible interface.
+
+       * idl/Accessibility_Accessible.idl:
+       Added four empty slots to Accessible interface.
+
+2002-11-15  Bill Haneman <bill.haneman@sun.com>
+
+       * idl/Accessibility_Registry.idl:
+       (KeyEventType, EventType):
+       Marked KeyEventType as deprecated; it duplicates
+       functionality of EventType, which has been extended to
+       include Mouse-button events.
+       (KeyEventTypeSeq): defined in terms of EventType.
+       (registerDeviceEventListener, deregisterDeviceEventListener):
+       New methods, for managing listeners to device events,
+       which potentially may consume them.     
+       
+       * cspi/spi-impl.h:
+       Added definition for AccessibleDeviceListener.
+
+       * cspi/spi-listener.h:
+       (enum AccessibleDeviceEventType):
+       Added SPI_BUTTON_PRESSED and SPI_BUTTON_RELEASED.
+       Typedef'd AccessibleKeyEventType to AccessibleDeviceEventType
+       for backwards compat.
+       (AccessibleKeystroke): Renamed AccessibleKeystroke to AccessibleDeviceEvent,
+       and typedef'd AccessibleKeystroke to it for back-compat.
+       (AccessibleDeviceListenerCB):
+       New function prototype typedef.
+
+       * cspi/spi.h:
+       (AccessibleDeviceEventMask): New typedef.
+       (AccessibleModifierMaskType): New typedef (renamed from AccessibleKeyMaskType).
+       (AccessibleKeyMaskType): 
+       Set equivalent to AccessibleModifierMaskType for back-compat.   
+       (SPI_createAccessibleKeystrokeListener):
+       (AccessibleKeystrokeListener_unref):
+       Deprecated in favor of equivalent (better-named) new API below..
+       keystroke listeners are like all device listeners.
+       (SPI_createAccessibleDeviceListener, AccessibleDeviceListener_unref)
+       New API names for old features :-).
+       (AccessibleDeviceListener_addCallback):
+       (AccessibleDeviceListener_removeCallback): 
+       (SPI_registerDeviceEventListener): 
+       (SPI_deregisterDeviceEventListener): 
+       New methods.
+       
+       * cspi/spi_event.c:
+       (SPI_createAccessibleKeystrokeListener):
+       Use new preferred API, cspi_device_listener_new() and
+       cspi_device_listener_add_cb().
+       (AccessibleKeystrokeListener_removeCallback):
+       Use new preferred API, cspi_device_listener_remove_cb().
+       (AccessibleKeystrokeListener_unref):
+       Use new preferred API, cspi_device_listener_unref().
+       (SPI_createAccessibleDeviceListener):
+       (AccessibleDeviceListener_addCallback):
+       (AccessibleDeviceListener_removeCallback):
+       Implementation of new API.
+
+       * cspi/spi_registry.c:
+       (SPI_registerDeviceEventListener):
+       (SPI_deregisterDeviceEventListener):
+       Implementation of new API.  Fixed memory leak and removed need to
+       allocate EventTypeSeq (thanks Michael for catching this).
+       Squashed a wayward CORBA_exception_free that shouldn't get called.
+
+       * cspi/bonobo/cspi-bonobo-listener.c:
+       (EventHandler):
+       Changed union (bin-and-api-compatibly) to refer to AccessibleDeviceListenerCB.
+       (cspi_key_event): renamed to cspi_device_event().
+       Internal use of CSpiKeystrokeListener changed to CSpiDeviceListener.
+       Extended to handle mouse button events as well as key events.
+       (CSpiKeystrokeListener):
+       Class superceded by CSpiDeviceListener.
+       (cspi_keystroke_listener_add_callback, cspi_keystroke_listener_get_corba):
+       These internal APIs changed to "*device_listener" from "*keystroke_listener".
+
+       * cspi/bonobo/cspi-bonobo-listener.h:
+       (CSpiKeystrokeListener):
+       Class superceded by CSpiDeviceListener.
+       (cspi_keystroke_listener_add_callback, cspi_keystroke_listener_get_corba):
+       These internal APIs changed to "*device_listener" from "*keystroke_listener".
+
+       * libspi/Makefile.am:
+       Replaced keystrokelistener.h and keystrokelistener.c
+       with devicelistener.h and devicelistener.c; keystrokelisener.h
+       stub retained for back-compat.
+
+       * libspi/keystrokelistener.c:
+       Removed file.
+
+       * libspi/libspi.h:
+       Replaced inclusion of keystrokelistener.h with devicelistener.h.        
+
+       * registryd/deviceeventcontroller.c:
+       (DEControllerListener): Added Accessibility_EventTypeSeq member.
+       (DEControllerKeyListener): Removed Accessibility_KeyEventTypeSeq member.
+       (DEControllerPrivateData): Added xkb settings data.
+       (spi_dec_poll_mouse_moved): Changed to dispatch device events for
+       button release events (which can't be captured via XGrabButton).
+       Don't dispatch via the 'normal' event mechanism if the device event was
+       consumed.
+       (spi_dec_key_listener_new, spi_key_listener_clone, spi_key_listener_data_free):
+       Handle the typeseq data in its new location (see above).
+       (spi_dec_listener_new, spi_listener_clone, spi_listener_clone_free):
+       New methods, for "generic" device listeners.
+       (spi_controller_register_device_listener):
+       Now handle mouse event listeners as well as key listeners.
+       (spi_controller_notify_mouselisteners):
+       New internal method.
+       (spi_device_event_controller_forward_mouse_event):
+       Now we notify mouse device listeners as well as generating the
+       non-consumable "mouse:" events.  
+       (global_filter_fn):
+       We must check and restore the XKB
+       modifier map if we consume the event, since the act of triggering
+       a mouse event will normally reset the XKB latch.  This is required for 
+       instance by GOK.
+       (spi_controller_register_with_devices):
+       Load the XKB settings when registering, and register for XKB 
+       state notify events. 
+       (spi_key_eventtype_seq_contains_event):
+       Renamed spi_eventtype_seq_contains_event, since it's used
+       internally for all device event types now.
+       (spi_key_event_matches_listener):
+       Uses spi_eventtype_seq_contains_event now.
+       (spi_device_event_controller_object_finalize):
+       Free the private data and the XkbKeyboard struct.
+       (impl_register_device_listener, impl_deregister_device_listener):
+       Implementation of new IDL.
+       (spi_deregister_controller_device_listener):
+       New internal method.
+       (dec_xkb_get_slowkeys_delay dec_xkb_get_bouncekeys_delay):
+       More efficient implementation, we don't have to create a new
+       XkbControls structure every time we query.
+       (spi_device_event_controller_class_init):
+       Initialize the epv entries for the new IDL.  Assign the 
+       "spi-dec-private" quark.
+       (spi_device_event_controller_init):
+       Initialize the private data.
+       (spi_device_event_controller_forward_key_event):
+       Removed a bogus CORBA_exception_free() call.
+       
+       * registryd/deviceeventcontroller.h:
+       Replaced inclusion of keystrokelistener.h with
+       devicelistener.h.
+
+       * test/event-listener-test.c:
+       (report_mouse_event):
+       New method.
+       (main):
+       Added mouse-event device listener.
+
+       * test/test-simple.c:
+       (create_test_window):
+       Fixed regression (we were instantiating a GtkRange,
+       which is now an abstract class).  Also fixed to match
+       existing AtkRole names, this seems to have changed in ATK
+       awhile ago; too late now I think, and the new
+       mechanism is at least elegant and consistent with the
+       glib enum "nick" APIs.  
+
 2002-11-15  Darren Kenny  <darren.kenny@sun.com>
 
        * idl/Accessibility_Relation.idl:
index 47353c3..b7aff56 100644 (file)
@@ -2,9 +2,9 @@ AC_INIT(idl/Accessibility.idl)
 
 AT_SPI_MAJOR_VERSION=1
 AT_SPI_MINOR_VERSION=1
-AT_SPI_MICRO_VERSION=2
-AT_SPI_INTERFACE_AGE=2
-AT_SPI_BINARY_AGE=2
+AT_SPI_MICRO_VERSION=3
+AT_SPI_INTERFACE_AGE=0
+AT_SPI_BINARY_AGE=3
 AT_SPI_VERSION="$AT_SPI_MAJOR_VERSION.$AT_SPI_MINOR_VERSION.$AT_SPI_MICRO_VERSION"
 AM_INIT_AUTOMAKE(at-spi, $AT_SPI_VERSION)
 AC_SUBST(AT_SPI_MAJOR_VERSION)
@@ -188,6 +188,15 @@ AC_TRY_CPP([#include <popt.h>
 You can download the latest version from ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/])
 ])
 
+REBUILD=\#
+if test "x$enable_rebuilds" = "xyes" && \
+       test -n "$PERL" && \
+       $PERL -e 'exit !($] >= 5.002)' > /dev/null 2>&1 && \
+     test -n "$AWK" ; then
+  REBUILD=
+fi
+AC_SUBST(REBUILD)
+
 AC_OUTPUT([
 Makefile
 libspi-1.0.pc
index d113597..9a5eb32 100644 (file)
@@ -3,6 +3,7 @@
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
  * Copyright 2002 Ximian Inc.
+ * Copyright 2002 Sun Microsystems, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -29,14 +30,14 @@ typedef struct
   union
     {
       AccessibleEventListenerCB     event;
-      AccessibleKeystrokeListenerCB key_event;
+      AccessibleDeviceListenerCB    device_event;
       gpointer                      method;
     } cb;
   gpointer user_data;
 } EventHandler;
 
 GObjectClass *event_parent_class;
-GObjectClass *keystroke_parent_class;
+GObjectClass *device_parent_class;
 
 /*
  * Misc. helpers.
@@ -175,55 +176,48 @@ cspi_event_listener_remove_cb (AccessibleEventListener  *al,
   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, callback);
 }
 
-/*
- * Key event dispatcher
+/* 
+ * Device event handler
  */
 static gboolean
-cspi_key_event (SpiKeystrokeListener            *listener,
-               const Accessibility_DeviceEvent *keystroke)
+cspi_device_event (SpiDeviceListener               *listener,
+                  const Accessibility_DeviceEvent *event)
 {
   GList *l;
-  CSpiKeystrokeListener *clistener = (CSpiKeystrokeListener *) listener;
-  AccessibleKeystroke akeystroke;
+  CSpiDeviceListener *clistener = (CSpiDeviceListener *) listener;
+  AccessibleDeviceEvent anevent;
   gboolean handled = FALSE;
 
-#ifdef SPI_KEYEVENT_DEBUG
-  fprintf (stderr, "%s%c",
-          (keystroke->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
-          ((keystroke->modifiers & SPI_KEYMASK_SHIFT)^(keystroke->modifiers & SPI_KEYMASK_SHIFTLOCK))?
-          (char) toupper((int) keystroke->keyID) : (char) tolower((int) keystroke->keyID));
-  
-  fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
-          (long) keystroke->keyID,
-          (unsigned int) keystroke->modifiers,
-          (int) keystroke->keycode,
-          (long int) keystroke->timestamp);
-#endif
-
-  switch (keystroke->type)
+  switch (event->type)
     {
-      case Accessibility_KEY_PRESSED:
-       akeystroke.type = SPI_KEY_PRESSED;
+      case Accessibility_KEY_PRESSED_EVENT:
+       anevent.type = SPI_KEY_PRESSED;
+       break;
+      case Accessibility_KEY_RELEASED_EVENT:
+       anevent.type = SPI_KEY_RELEASED;
+       break;
+      case Accessibility_BUTTON_PRESSED_EVENT:
+       anevent.type = SPI_BUTTON_PRESSED;
        break;
-      case Accessibility_KEY_RELEASED:
-       akeystroke.type = SPI_KEY_RELEASED;
+      case Accessibility_BUTTON_RELEASED_EVENT:
+       anevent.type = SPI_BUTTON_RELEASED;
        break;
       default:
-       akeystroke.type = 0;
+       anevent.type = 0;
        break;
     }
-  akeystroke.keyID     = keystroke->id;
-  akeystroke.keycode   = keystroke->hw_code;
-  akeystroke.timestamp = keystroke->timestamp;
-  akeystroke.keystring = g_strdup (keystroke->event_string);
-  akeystroke.modifiers = keystroke->modifiers;
+  anevent.keyID     = event->id;
+  anevent.keycode   = event->hw_code;
+  anevent.timestamp = event->timestamp;
+  anevent.keystring = g_strdup (event->event_string);
+  anevent.modifiers = event->modifiers;
 
   /* FIXME: re-enterancy hazard on this list */
   for (l = clistener->callbacks; l; l = l->next)
     {
       EventHandler *eh = l->data;
 
-      if ((handled = eh->cb.key_event (&akeystroke, eh->user_data)))
+      if ((handled = eh->cb.device_event (&anevent, eh->user_data)))
         {
          break;
        }
@@ -233,15 +227,14 @@ cspi_key_event (SpiKeystrokeListener            *listener,
 }
 
 static void
-cspi_keystroke_listener_init (CSpiKeystrokeListener *listener)
+cspi_device_listener_init (CSpiDeviceListener *listener)
 {
 }
 
-
 static void
-cspi_keystroke_listener_finalize (GObject *object)
+cspi_device_listener_finalize (GObject *object)
 {
-  CSpiKeystrokeListener *listener = (CSpiKeystrokeListener *) object;
+  CSpiDeviceListener *listener = (CSpiDeviceListener *) object;
   GList *l;
   
   for (l = listener->callbacks; l; l = l->next)
@@ -251,54 +244,52 @@ cspi_keystroke_listener_finalize (GObject *object)
   
   g_list_free (listener->callbacks);
 
-  keystroke_parent_class->finalize (object);
+  device_parent_class->finalize (object);
 }
 
 static void
-cspi_keystroke_listener_class_init (CSpiKeystrokeListenerClass *klass)
+cspi_device_listener_class_init (CSpiDeviceListenerClass *klass)
 {
   GObjectClass *object_class = (GObjectClass *) klass;
 
-  keystroke_parent_class = g_type_class_peek_parent (klass);
-  object_class->finalize = cspi_keystroke_listener_finalize;
+  device_parent_class = g_type_class_peek_parent (klass);
+  object_class->finalize = cspi_device_listener_finalize;
 
-  klass->key_event = cspi_key_event;
+  klass->device_event = cspi_device_event;
 }
 
-BONOBO_TYPE_FUNC (CSpiKeystrokeListener, 
-                 spi_keystroke_listener_get_type (),
-                 cspi_keystroke_listener);
+BONOBO_TYPE_FUNC (CSpiDeviceListener, 
+                 spi_device_listener_get_type (),
+                 cspi_device_listener);
 
 gpointer
-cspi_keystroke_listener_new (void)
+cspi_device_listener_new (void)
 {
-  CSpiEventListener *listener;
-
-  listener = g_object_new (cspi_keystroke_listener_get_type (), NULL);
+  CSpiEventListener *listener = g_object_new (cspi_device_listener_get_type (), NULL);
 
   return listener;
 }
 
 void
-cspi_keystroke_listener_add_cb (AccessibleKeystrokeListener  *al,
-                               AccessibleKeystrokeListenerCB callback,
-                               void                         *user_data)
+cspi_device_listener_add_cb (AccessibleDeviceListener  *al,
+                            AccessibleDeviceListenerCB callback,
+                            void                      *user_data)
 {
-  CSpiKeystrokeListener *listener = al;
+  CSpiDeviceListener *listener = al;
 
-  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener));
 
   listener->callbacks = g_list_prepend (listener->callbacks,
                                        cspi_event_handler_new (callback, user_data));
 }
 
 void
-cspi_keystroke_listener_remove_cb (AccessibleKeystrokeListener  *al,
-                                  AccessibleKeystrokeListenerCB callback)
+cspi_device_listener_remove_cb (AccessibleDeviceListener  *al,
+                               AccessibleDeviceListenerCB callback)
 {
-  CSpiKeystrokeListener *listener = al;
+  CSpiDeviceListener *listener = al;
 
-  g_return_if_fail (CSPI_IS_KEYSTROKE_LISTENER (listener));
+  g_return_if_fail (CSPI_IS_DEVICE_LISTENER (listener));
 
   listener->callbacks = cspi_event_list_remove_by_cb (listener->callbacks, callback);
 }
@@ -310,7 +301,7 @@ cspi_event_listener_unref (AccessibleEventListener *listener)
 }
 
 void
-cspi_keystroke_listener_unref (AccessibleKeystrokeListener *listener)
+cspi_device_listener_unref (AccessibleDeviceListener *listener)
 {
   bonobo_object_unref (BONOBO_OBJECT (listener));
 }
@@ -323,7 +314,7 @@ cspi_event_listener_get_corba (AccessibleEventListener *listener)
 }
 
 CORBA_Object
-cspi_keystroke_listener_get_corba (AccessibleKeystrokeListener *listener)
+cspi_device_listener_get_corba (AccessibleDeviceListener *listener)
 {
   return BONOBO_OBJREF (listener);
 }
index 58c818b..8dbcf9e 100644 (file)
@@ -24,7 +24,7 @@
 #define __SPI_LISTENER_IMP_H__
 
 #include <libspi/eventlistener.h>
-#include <libspi/keystrokelistener.h>
+#include <libspi/devicelistener.h>
 #include <cspi/spi-impl.h>
 #include <cspi/spi-listener.h>
 
@@ -44,19 +44,20 @@ typedef SpiEventListenerClass CSpiEventListenerClass;
 
 GType cspi_event_listener_get_type (void);
 
-#define CSPI_KEYSTROKE_LISTENER_TYPE        (cspi_keystroke_listener_get_type ())
-#define CSPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListener))
-#define CSPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_KEYSTROKE_LISTENER_TYPE, CSpiKeystrokeListenerClass))
-#define CSPI_IS_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_KEYSTROKE_LISTENER_TYPE))
-#define CSPI_IS_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_KEYSTROKE_LISTENER_TYPE))
+#define CSPI_DEVICE_LISTENER_TYPE        (cspi_device_listener_get_type ())
+#define CSPI_DEVICE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), CSPI_DEVICE_LISTENER_TYPE, CSpiDeviceListener))
+#define CSPI_DEVICE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), CSPI_DEVICE_LISTENER_TYPE, CSpiDeviceListenerClass))
+#define CSPI_IS_DEVICE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), CSPI_DEVICE_LISTENER_TYPE))
+#define CSPI_IS_DEVICE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CSPI_DEVICE_LISTENER_TYPE))
 
 typedef struct {
-       SpiKeystrokeListener parent;
-       GList               *callbacks;
-} CSpiKeystrokeListener;
-typedef SpiKeystrokeListenerClass CSpiKeystrokeListenerClass;
+       SpiDeviceListener parent;
+       GList            *callbacks;
+} CSpiDeviceListener;
+typedef SpiDeviceListenerClass CSpiDeviceListenerClass;
 
-GType cspi_keystroke_listener_get_type (void);
+GType cspi_device_listener_get_type (void);
+gpointer cspi_device_listener_new (void);
 
 G_END_DECLS
 
index d71a822..d29d014 100644 (file)
@@ -52,6 +52,7 @@ typedef Accessible AccessibilityRegistry;
 
 typedef void AccessibleEventListener;
 typedef void AccessibleKeystrokeListener;
+typedef void AccessibleDeviceListener;
 
 typedef unsigned int SPIBoolean;
 
index c942179..63384f6 100644 (file)
@@ -42,19 +42,24 @@ typedef struct {
 
 typedef enum {
   SPI_KEY_PRESSED  = 1<<0,
-  SPI_KEY_RELEASED = 1<<1
-} AccessibleKeyEventType;
+  SPI_KEY_RELEASED = 1<<1,
+  SPI_BUTTON_PRESSED = 1<<2,
+  SPI_BUTTON_RELEASED = 1<<3
+} AccessibleDeviceEventType;
 
+typedef AccessibleDeviceEventType AccessibleKeyEventType;
 
 typedef struct {
   long                   keyID;
   short                  keycode;
   char *                 keystring;
   long                   timestamp;
-  AccessibleKeyEventType type;
+  AccessibleDeviceEventType type;
   unsigned short         modifiers;
   SPIBoolean             is_text;      
-} AccessibleKeystroke;
+} AccessibleDeviceEvent;
+
+typedef AccessibleDeviceEvent AccessibleKeystroke;
 
 /*
  * Function prototype typedefs for Event Listener Callbacks.
@@ -69,6 +74,8 @@ typedef void       (*AccessibleEventListenerCB)     (const AccessibleEvent     *
                                                     void                      *user_data);
 typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (const AccessibleKeystroke *stroke,
                                                     void                      *user_data);
+typedef SPIBoolean (*AccessibleDeviceListenerCB)    (const AccessibleDeviceEvent *stroke,
+                                                    void                      *user_data);
 
 #ifdef  __cplusplus
 }
index 5e5e0f7..3105446 100644 (file)
@@ -100,6 +100,7 @@ typedef enum {
 } AccessibleKeyListenerSyncType;
 
 typedef unsigned long AccessibleKeyEventMask;
+typedef unsigned long AccessibleDeviceEventMask;
 
 /**
  * AccessibleComponentLayer:
@@ -155,8 +156,8 @@ typedef struct _AccessibleKeySet
  **/
 #define SPI_KEYSET_ALL_KEYS NULL
 
-typedef unsigned long AccessibleKeyMaskType;
-
+typedef unsigned long AccessibleModifierMaskType;
+typedef AccessibleModifierMaskType AccessibleKeyMaskType;
 
 /* Basic SPI initialization and event loop function prototypes */
 
@@ -189,7 +190,9 @@ SPIBoolean                AccessibleEventListener_removeCallback (
 void                      AccessibleEventListener_unref (
                                                   AccessibleEventListener  *listener);
 
-/* Keystroke Listener creation and support.  */
+/* Device Event Listener creation and support.  */
+
+/* First four are deprecated in favor of the last four; really just a re-name */
 
 AccessibleKeystrokeListener * SPI_createAccessibleKeystrokeListener (
                                        AccessibleKeystrokeListenerCB callback,
@@ -204,6 +207,19 @@ SPIBoolean                    AccessibleKeystrokeListener_removeCallback (
 void                          AccessibleKeystrokeListener_unref (
                                        AccessibleKeystrokeListener *listener);
 
+AccessibleDeviceListener   * SPI_createAccessibleDeviceListener (
+                                       AccessibleDeviceListenerCB callback,
+                                       void                      *user_data);
+SPIBoolean                    AccessibleDeviceListener_addCallback (
+                                       AccessibleDeviceListener  *listener,
+                                       AccessibleDeviceListenerCB callback,
+                                       void                      *user_data);
+SPIBoolean                    AccessibleDeviceListener_removeCallback (
+                                       AccessibleDeviceListener  *listener,
+                                       AccessibleDeviceListenerCB callback);
+void                          AccessibleDeviceListener_unref (
+                                       AccessibleDeviceListener *listener);
+
 /* Global functions serviced by the registry */
 
 SPIBoolean SPI_registerGlobalEventListener           (
@@ -224,6 +240,14 @@ SPIBoolean SPI_deregisterAccessibleKeystrokeListener (
                                       AccessibleKeystrokeListener *listener,
                                       AccessibleKeyMaskType        modmask);
 
+SPIBoolean SPI_registerDeviceEventListener   (
+                                       AccessibleDeviceListener   *listener,
+                                      AccessibleDeviceEventMask   eventmask,
+                                      void                       *filter);
+SPIBoolean SPI_deregisterDeviceEventListener (
+                                      AccessibleDeviceListener   *listener,
+                                      void                       *filter);
+
 int         SPI_getDesktopCount                  (void);
 Accessible *SPI_getDesktop                       (int i);
 int         SPI_getDesktopList                   (Accessible ***desktop_list);
index b6887e9..adfd1d1 100644 (file)
@@ -104,6 +104,25 @@ AccessibleAction_getDescription (AccessibleAction *obj,
  *
  * Get the keybindings for the @i-th action invokable on an
  *      object implementing #AccessibleAction, if any are defined.
+ *      The keybindings string format is as follows:
+ *        there are multiple parts to a keybinding string (typically 3).
+ *        They are delimited with ";".  The first is the action's
+ *        keybinding which is usable if the object implementing the action
+ *        is currently posted to the screen, e.g. if a menu is posted 
+ *        then these keybindings for the corresponding menu-items are
+ *        available.  The second keybinding substring is the full key sequence
+ *        necessary to post the action's widget and activate it, e.g. for
+ *        a menu item such as "File->Open" it would both post the menu and
+ *        activate the item.  Thus the second keybinding string is available
+ *        during the lifetime of the containing toplevel window as a whole,
+ *        whereas the first keybinding string only works while the object
+ *        implementing AtkAction is posted.  The third (and optional)
+ *        keybinding string is the "keyboard shortcut" which invokes the 
+ *        action without posting any menus. 
+ *        Meta-keys are indicated by the conventional strings
+ *        "<Control>", "<Alt>", "<Shift>", "<Mod2>",
+ *        etc. (we use the same string as gtk_accelerator_name() in 
+ *        gtk+-2.X.
  *
  * Returns: a UTF-8 string which can be parsed to determine the @i-th
  *       invokable action's keybindings.
index f36a24a..5eb5c16 100644 (file)
@@ -22,8 +22,7 @@
  */
 
 #include <cspi/spi-private.h>
-
-
+#include <cspi/bonobo/cspi-bonobo-listener.h>
 
 /**
  * SPI_freeAccessibleKeySet:
@@ -198,10 +197,10 @@ AccessibleKeystrokeListener *
 SPI_createAccessibleKeystrokeListener (AccessibleKeystrokeListenerCB callback,
                                       void                         *user_data)
 {
-  AccessibleKeystrokeListener *listener = cspi_keystroke_listener_new ();
+  AccessibleDeviceListener *listener = cspi_device_listener_new ();
   if (callback)
     {
-      AccessibleKeystrokeListener_addCallback (listener, callback, user_data);
+      AccessibleDeviceListener_addCallback (listener, callback, user_data);
     }
   return listener;
 }
@@ -222,7 +221,7 @@ AccessibleKeystrokeListener_addCallback (AccessibleKeystrokeListener *listener,
                                         AccessibleKeystrokeListenerCB callback,
                                         void                         *user_data)
 {
-  cspi_keystroke_listener_add_cb (listener, callback, user_data);
+  cspi_device_listener_add_cb (listener, callback, user_data);
   return TRUE;
 }
 
@@ -240,7 +239,7 @@ SPIBoolean
 AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listener,
                                            AccessibleKeystrokeListenerCB callback)
 {
-  cspi_keystroke_listener_remove_cb (listener, callback);
+  cspi_device_listener_remove_cb (listener, callback);
   return TRUE;
 }
 
@@ -253,5 +252,77 @@ AccessibleKeystrokeListener_removeCallback (AccessibleKeystrokeListener *listene
 void
 AccessibleKeystrokeListener_unref (AccessibleKeystrokeListener *listener)
 {
-  cspi_keystroke_listener_unref (listener);
+  cspi_device_listener_unref (listener);
+}
+
+/**
+ * SPI_createAccessibleDeviceListener:
+ * @callback : an #AccessibleDeviceListenerCB callback function, or NULL.
+ * @user_data: a pointer to data which will be passed to the callback when invoked.
+ *
+ * Create a new #AccessibleDeviceListener with a specified callback function.
+ *
+ * Returns: a pointer to a newly-created #AccessibleDeviceListener.
+ *
+ **/
+AccessibleDeviceListener *
+SPI_createAccessibleDeviceListener (AccessibleDeviceListenerCB callback,
+                                      void                         *user_data)
+{
+  AccessibleDeviceListener *listener = cspi_device_listener_new ();
+  if (callback)
+    {
+      AccessibleDeviceListener_addCallback (listener, callback, user_data);
+    }
+  return listener;
+}
+
+/**
+ * AccessibleDeviceListener_addCallback:
+ * @listener: the #AccessibleDeviceListener instance to modify.
+ * @callback: an #AccessibleDeviceListenerCB function pointer.
+ * @user_data: a pointer to data which will be passed to the callback when invoked.
+ *
+ * Add an in-process callback function to an existing #AccessibleDeviceListener.
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ *
+ **/
+SPIBoolean
+AccessibleDeviceListener_addCallback (AccessibleDeviceListener *listener,
+                                        AccessibleDeviceListenerCB callback,
+                                        void                         *user_data)
+{
+  cspi_device_listener_add_cb (listener, callback, user_data);
+  return TRUE;
+}
+
+/**
+ * AccessibleDeviceListener_removeCallback:
+ * @listener: the #AccessibleDeviceListener instance to modify.
+ * @callback: an #AccessibleDeviceListenerCB function pointer.
+ *
+ * Remove an in-process callback function from an existing #AccessibleDeviceListener.
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ *
+ **/
+SPIBoolean
+AccessibleDeviceListener_removeCallback (AccessibleDeviceListener *listener,
+                                           AccessibleDeviceListenerCB callback)
+{
+  cspi_device_listener_remove_cb (listener, callback);
+  return TRUE;
+}
+
+/**
+ * AccessibleDeviceListener_unref:
+ * @listener: a pointer to the #AccessibleDeviceListener being operated on.
+ *
+ * Decrements an #AccessibleDeviceListener's reference count.
+ **/
+void
+AccessibleDeviceListener_unref (AccessibleDeviceListener *listener)
+{
+  cspi_device_listener_unref (listener);
 }
index 1adcb3c..e97ffc1 100644 (file)
@@ -337,6 +337,7 @@ SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
   Accessibility_ControllerEventMask   controller_event_mask;
   Accessibility_DeviceEventController device_event_controller;
   Accessibility_EventListenerMode     listener_mode;
+  Accessibility_KeyEventType          key_event_types [2];
   SPIBoolean                          retval = FALSE;
 
   if (!listener)
@@ -360,7 +361,7 @@ SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
          key_set._buffer[i].keysym = keys->keysyms[i];
          if (keys->keystrings && keys->keystrings[i]) 
            {
-             key_set._buffer[i].keystring = keys->keystrings[i];
+             key_set._buffer[i].keystring = CORBA_string_dup(keys->keystrings[i]);
            } 
           else 
             {
@@ -375,20 +376,8 @@ SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
     }
        
   /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
-  mask = 1;
-  i = 0;
-  do
-    {
-      if (mask & eventmask)
-        {
-          ++i; 
-       }
-      mask <<= 1;
-    }
-  while (mask & 0xFFFF);
-  
-  key_events._buffer = Accessibility_KeyEventTypeSeq_allocbuf (i);
   i = 0;
+  key_events._buffer = key_event_types;
   if (eventmask & SPI_KEY_PRESSED)
     {
       key_events._buffer[i++] = Accessibility_KEY_PRESSED;
@@ -417,6 +406,8 @@ SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
     &listener_mode,
     cspi_ev ());
 
+  CORBA_free (key_set._buffer);
+
   cspi_return_val_if_ev ("registering keystroke listener", FALSE);
 
   cspi_release_unref (device_event_controller);
@@ -477,6 +468,111 @@ SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener
 }
 
 /**
+ * SPI_registerDeviceEventListener:
+ * @listener:  a pointer to the #AccessibleDeviceListener which requests
+ *             the events.
+ * @eventmask: an #AccessibleDeviceEventMask mask indicating which
+ *             types of key events are requested (#SPI_KEY_PRESSED, etc.).
+ *             
+ * Register a listener for device events, for instance button events.
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ **/
+SPIBoolean
+SPI_registerDeviceEventListener (AccessibleDeviceListener  *listener,
+                                AccessibleDeviceEventMask  eventmask,
+                                void                      *filter)
+{
+  Accessibility_DeviceEventController device_event_controller;
+  SPIBoolean                          retval = FALSE;
+  Accessibility_EventTypeSeq          event_types;
+  Accessibility_EventType             event_type_buffer[2];
+  gint                                i, mask;
+
+  if (!listener)
+    {
+      return retval;
+    }
+
+  device_event_controller = 
+    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
+
+  cspi_return_val_if_ev ("getting event controller", FALSE);
+
+  /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */
+  
+  event_types._buffer = event_type_buffer;
+  i = 0;
+
+  if (eventmask & SPI_BUTTON_PRESSED)
+    {
+      event_types._buffer[i++] = Accessibility_BUTTON_PRESSED_EVENT;
+    }
+  if (eventmask & SPI_BUTTON_RELEASED)
+    {
+      event_types._buffer[i++] = Accessibility_BUTTON_RELEASED_EVENT;
+    }
+
+  event_types._length = i;
+  
+  retval = Accessibility_DeviceEventController_registerDeviceEventListener (
+    device_event_controller,
+    cspi_event_listener_get_corba (listener),
+    &event_types,
+    cspi_ev ());
+
+  cspi_return_val_if_ev ("registering keystroke listener", FALSE);
+
+  cspi_release_unref (device_event_controller);
+
+  return retval;
+}
+
+/**
+ * SPI_deregisterDeviceEventListener:
+ * @listener: a pointer to the #AccessibleDeviceListener for which
+ *            device events are requested.
+ *
+ * Removes a device event listener from the registry's listener queue,
+ *            ceasing notification of events of the specified type.
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ **/
+SPIBoolean
+SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener,
+                                  void                     *filter)
+{
+  Accessibility_ControllerEventMask   controller_event_mask;
+  Accessibility_DeviceEventController device_event_controller;
+  Accessibility_EventTypeSeq       event_types;
+
+  if (!listener)
+    {
+      return FALSE;
+    }
+
+  device_event_controller = 
+    Accessibility_Registry_getDeviceEventController (cspi_registry (), cspi_ev ());
+
+  cspi_return_val_if_ev ("getting keystroke listener", FALSE);
+
+  event_types._buffer = Accessibility_EventTypeSeq_allocbuf (2);
+  event_types._length = 2;
+  event_types._buffer[0] = Accessibility_BUTTON_PRESSED_EVENT;
+  event_types._buffer[1] = Accessibility_BUTTON_RELEASED_EVENT;
+
+  Accessibility_DeviceEventController_deregisterDeviceEventListener (
+    device_event_controller,
+    cspi_event_listener_get_corba (listener),
+    &event_types,    
+    cspi_ev ());
+
+  cspi_release_unref (device_event_controller);
+
+  return TRUE;
+}
+
+/**
  * SPI_generateKeyboardEvent:
  * @keyval: a long integer indicating the keycode or keysym of the key event
  *           being synthesized.
index 35e33c2..32fabba 100644 (file)
@@ -174,10 +174,14 @@ AccessibleText_getCaretOffset (AccessibleText *obj)
  *
  * Get the attributes applied to a range of text from an #AccessibleText
  *          object, and the bounds of the range.
+ *          The text attributes correspond to CSS attributes where possible,
+ *          keys and values are delimited from one another via ":", and
+ *          the delimiter between key/value pairs is ";". Thus 
+ *          "font-size:10;foreground-color:0,0,0" would be a valid
+ *          return string.
  *
  * Returns: a text string describing the attributes occurring within the
- *          attribute run containing @offset, encoded as UTF-8 and
- *          delimited by ':'
+ *          attribute run containing @offset, encoded as UTF-8.
  **/
 char *
 AccessibleText_getAttributes (AccessibleText *obj,
index 23adfde..f9cc3f7 100644 (file)
@@ -83,13 +83,11 @@ Registry queries
 </para>
 
 
-<!-- ##### ENUM AccessibleKeyEventType ##### -->
+<!-- ##### TYPEDEF AccessibleKeyEventType ##### -->
 <para>
 
 </para>
 
-@SPI_KEY_PRESSED: 
-@SPI_KEY_RELEASED: 
 
 <!-- ##### ENUM AccessibleKeyListenerSyncType ##### -->
 <para>
index d3e7e40..191ef7d 100644 (file)
@@ -124,6 +124,11 @@ module Accessibility {
      * Returns: a @StateSet encapsulating the currently true states of the object.
      **/
     StateSet   getState ();
+
+    void        unImplemented ();
+    void        unImplemented2 ();
+    void        unImplemented3 ();
+    void        unImplemented4 ();
   };
 };
 
index 50482eb..e62a7b8 100644 (file)
@@ -99,6 +99,11 @@ module Accessibility {
      * Returns: %true if the request succeeded, %false otherwise.
      **/
     boolean       resume ();
+
+    void          unImplemented_ ();
+    void          unImplemented2_ ();
+    void          unImplemented3_ ();
+    void          unImplemented4_ ();
   };
 };
 
index 7a0cfb4..69a7aa2 100644 (file)
@@ -37,8 +37,8 @@ module Accessibility {
           *
           * placeholders for future expansion.
           */
-         void unImplemented ();
-         void unImplemented2 ();
+         void unImplemented_ ();
+         void unImplemented2_ ();
   };
 };
 
index ba0465c..23c66fa 100644 (file)
@@ -2,7 +2,7 @@
  * AT-SPI - Assistive Technology Service Provider Interface 
  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  *
- * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2001, 2002 Sun Microsystems Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -30,14 +30,18 @@ module Accessibility
   interface Accessible;
 
   struct Event {
-    string type;
+    string     type;
     Accessible source;
-    long detail1;
-    long detail2;
+    long       detail1;
+    long       detail2;
   };
 
   interface EventListener : Bonobo::Unknown {
     void notifyEvent (in Event e);
+    void unImplemented_ ();
+    void unImplemented2_ ();
+    void unImplemented3_ ();
+    void unImplemented4_ ();
   };
 };
 
index 0b5f27e..97dc74f 100644 (file)
@@ -28,5 +28,9 @@ module Accessibility {
     long getNLinks ();
     Hyperlink getLink (in long linkIndex);
     long getLinkIndex (in long characterIndex);
+    void unImplemented ();
+    void unImplemented2 ();
+    void unImplemented3 ();
+    void unImplemented4 ();
   };
 };
index 74165cf..46fb458 100644 (file)
@@ -153,6 +153,7 @@ module Accessibility {
        void unImplemented2 ();
     };
 
+  /* Deprecated, DO NOT USE! */
   enum KeyEventType {
     KEY_PRESSED,
     KEY_RELEASED
@@ -160,7 +161,9 @@ module Accessibility {
 
   enum EventType {
     KEY_PRESSED_EVENT,
-    KEY_RELEASED_EVENT
+    KEY_RELEASED_EVENT,
+    BUTTON_PRESSED_EVENT,
+    BUTTON_RELEASED_EVENT
   };
 
   enum KeySynthType {
@@ -208,10 +211,15 @@ module Accessibility {
   };   
 
   typedef sequence< KeyDefinition > KeySet;
-  typedef sequence< KeyEventType > KeyEventTypeSeq;
+  typedef sequence< EventType > KeyEventTypeSeq;
+  typedef sequence< EventType > EventTypeSeq;
 
   interface DeviceEventListener : Bonobo::Unknown {
         boolean notifyEvent (in DeviceEvent event);
+        void    unImplemented__ ();
+        void    unImplemented_2_ ();
+        void    unImplemented_3_ ();
+        void    unImplemented_4_ ();
   };
 
   interface DeviceEventController : Bonobo::Unknown {
@@ -255,6 +263,34 @@ module Accessibility {
                                          in ControllerEventMask mask,
                                          in KeyEventTypeSeq type);
     
+       /**
+         * registerDeviceEventListener:
+         * @listener: a @DeviceEventListener which will intercept events.
+        * @typeseq:  an @EventTypeSeq indicating which event types to listen for.
+        * Returns: %true if successful, %false if not
+         *
+         * Register to intercept events, and either pass them on or
+         * consume them. To listen to keyboard events use registerKeystrokeListener
+        * instead.
+         *
+        **/
+        boolean registerDeviceEventListener (in DeviceEventListener listener,
+                                            in EventTypeSeq typeseq);
+    
+       /**
+         * deregisterDeviceEventListener:
+         * @listener: a @DeviceEventListener which will intercept events.
+        * @typeseq:  an @EventTypeSeq indicating which event types to stop
+        *            listening for.
+        *
+        * Returns: void
+         *
+         * De-register a previously registered keyboard eventlistener.
+         *
+        **/
+        void deregisterDeviceEventListener (in DeviceEventListener listener,
+                                           in EventTypeSeq typeseq);
+    
         boolean notifyListenersSync (in DeviceEvent event);
 
         oneway void notifyListenersAsync (in DeviceEvent event);
index cf77e28..16848b9 100644 (file)
@@ -24,6 +24,7 @@ libspiinclude_HEADERS =               \
        hyperlink.h             \
        hypertext.h             \
        image.h                 \
+       devicelistener.h        \
        keystrokelistener.h     \
        keymasks.h              \
        libspi.h                \
@@ -74,7 +75,7 @@ libspi_la_SOURCES =           \
        hyperlink.c             \
        hypertext.c             \
        image.c                 \
-       keystrokelistener.c     \
+       devicelistener.c        \
        relation.c              \
        remoteobject.c          \
        selection.c             \
diff --git a/libspi/devicelistener.c b/libspi/devicelistener.c
new file mode 100644 (file)
index 0000000..cdafb85
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* devicelistener.c: implement the DeviceListener interface */
+
+#include <config.h>
+#ifdef SPI_DEBUG
+#  include <stdio.h>
+#endif
+#include <libspi/listener.h>
+#include <libspi/devicelistener.h>
+
+/* Our parent Gtk object type  */
+#define PARENT_TYPE BONOBO_TYPE_OBJECT
+
+enum {
+       DEVICE_EVENT,
+       LAST_SIGNAL
+};
+static guint signals [LAST_SIGNAL];
+
+/*
+ * CORBA Accessibility::DeviceListener::keyEvent method implementation
+ */
+static CORBA_boolean
+impl_device_event (PortableServer_Servant           servant,
+                  const Accessibility_DeviceEvent *key,
+                  CORBA_Environment               *ev)
+{
+  gboolean was_consumed = FALSE;
+  SpiDeviceListener *listener = SPI_DEVICE_LISTENER (
+         bonobo_object_from_servant (servant));
+
+  g_signal_emit (G_OBJECT (listener), signals [DEVICE_EVENT], 0, key, &was_consumed);
+
+  return was_consumed;
+}
+
+static gboolean
+boolean_handled_accumulator (GSignalInvocationHint *ihint,
+                            GValue                *return_accu,
+                            const GValue          *handler_return,
+                            gpointer               dummy)
+{
+  gboolean continue_emission;
+  gboolean signal_handled;
+  
+  signal_handled = g_value_get_boolean (handler_return);
+  g_value_set_boolean (return_accu, signal_handled);
+  continue_emission = !signal_handled;
+  
+  return continue_emission;
+}
+
+void
+marshal_BOOLEAN__POINTER (GClosure     *closure,
+                         GValue       *return_value,
+                         guint         n_param_values,
+                         const GValue *param_values,
+                         gpointer      invocation_hint,
+                         gpointer      marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer     data1,
+                                                     gpointer     arg_1,
+                                                     gpointer     data2);
+  register GMarshalFunc_BOOLEAN__POINTER callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       g_value_get_pointer (param_values + 1),
+                       data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+static void
+spi_device_listener_class_init (SpiDeviceListenerClass *klass)
+{
+  POA_Accessibility_DeviceEventListener__epv *epv = &klass->epv;
+  
+  signals [DEVICE_EVENT] = g_signal_new (
+    "device_event",
+    G_TYPE_FROM_CLASS (klass),
+    G_SIGNAL_RUN_LAST,
+    G_STRUCT_OFFSET (SpiDeviceListenerClass, device_event),
+    boolean_handled_accumulator, NULL,
+    marshal_BOOLEAN__POINTER,
+    G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+  
+  epv->notifyEvent = impl_device_event;
+}
+
+static void
+spi_device_listener_init (SpiDeviceListener *device_listener)
+{
+}
+
+BONOBO_TYPE_FUNC_FULL (SpiDeviceListener,
+                      Accessibility_DeviceEventListener,
+                      BONOBO_TYPE_OBJECT,
+                      spi_device_listener);
+
+SpiDeviceListener *
+spi_device_listener_new (void)
+{
+    SpiDeviceListener *retval = g_object_new (
+           SPI_DEVICE_LISTENER_TYPE, NULL);
+    return retval;
+}
diff --git a/libspi/devicelistener.h b/libspi/devicelistener.h
new file mode 100644 (file)
index 0000000..9c9e40d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SPI_DEVICE_LISTENER_H_
+#define SPI_DEVICE_LISTENER_H_
+
+#include <bonobo/bonobo-object.h>
+#include <atk/atkobject.h>
+#include <libspi/Accessibility.h>
+#include <libspi/keymasks.h>
+
+G_BEGIN_DECLS
+
+#define SPI_DEVICE_LISTENER_TYPE        (spi_device_listener_get_type ())
+#define SPI_DEVICE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_DEVICE_LISTENER_TYPE, SpiDeviceListener))
+#define SPI_DEVICE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_DEVICE_LISTENER_TYPE, SpiDeviceListenerClass))
+#define SPI_IS_DEVICE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_DEVICE_LISTENER_TYPE))
+#define SPI_IS_DEVICE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_LISTENER_TYPE))
+
+typedef struct _SpiDeviceListener SpiDeviceListener;
+
+struct _SpiDeviceListener {
+        BonoboObject parent;
+};
+
+typedef struct {
+        BonoboObjectClass parent_class;
+        POA_Accessibility_DeviceEventListener__epv epv;
+
+       gboolean (*device_event) (SpiDeviceListener *listener,
+                                 const Accessibility_DeviceEvent *key);
+} SpiDeviceListenerClass;
+
+GType                  spi_device_listener_get_type        (void);
+SpiDeviceListener     *spi_device_listener_new             (void);
+
+G_END_DECLS
+
+#endif /* DEVICE_SPI_LISTENER_H_ */
index e341c7e..ed2ba45 100644 (file)
 #ifndef SPI_KEYSTROKE_LISTENER_H_
 #define SPI_KEYSTROKE_LISTENER_H_
 
-#include <bonobo/bonobo-object.h>
-#include <atk/atkobject.h>
-#include <libspi/Accessibility.h>
-#include <libspi/keymasks.h>
-
 G_BEGIN_DECLS
 
-#define SPI_KEYSTROKE_LISTENER_TYPE        (spi_keystroke_listener_get_type ())
-#define SPI_KEYSTROKE_LISTENER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_KEYSTROKE_LISTENER_TYPE, SpiKeystrokeListener))
-#define SPI_KEYSTROKE_LISTENER_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_KEYSTROKE_LISTENER_TYPE, SpiKeystrokeListenerClass))
+#include <libspi/devicelistener.h>
+
+#define SPI_KEYSTROKE_LISTENER_TYPE        SPI_DEVICE_LISTENER_TYPE
+#define SPI_KEYSTROKE_LISTENER(o)          SPI_DEVICE_LISTENER(o)
+#define SPI_KEYSTROKE_LISTENER_CLASS(k)    SPI_DEVICE_LISTENER_CLASS(k)
 #define SPI_IS_KEYSTROKE_LISTENER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_KEYSTROKE_LISTENER_TYPE))
 #define SPI_IS_KEYSTROKE_LISTENER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_KEYSTROKE_LISTENER_TYPE))
 
-typedef struct _SpiKeystrokeListener SpiKeystrokeListener;
-
-struct _SpiKeystrokeListener {
-        BonoboObject parent;
-};
-
-typedef struct {
-        BonoboObjectClass parent_class;
-        POA_Accessibility_DeviceEventListener__epv epv;
+typedef struct _SpiDeviceListener SpiKeystrokeListener;
 
-       gboolean (*key_event) (SpiKeystrokeListener *listener,
-                              const Accessibility_DeviceEvent *key);
-} SpiKeystrokeListenerClass;
+typedef SpiDeviceListenerClass SpiKeystrokeListenerClass;
 
-GType                  spi_keystroke_listener_get_type        (void);
-SpiKeystrokeListener  *spi_keystroke_listener_new             (void);
+#define spi_keystroke_listener_get_type spi_device_listener_get_type
+#define spi_keystroke_listener_new      spi_device_listener_new
 
 G_END_DECLS
 
index 1bc20b7..ae47293 100644 (file)
@@ -41,7 +41,7 @@
 #include <libspi/value.h>
 #include <libspi/listener.h>
 #include <libspi/eventlistener.h>
-#include <libspi/keystrokelistener.h>
+#include <libspi/devicelistener.h>
 #include <libspi/keymasks.h>
 #include <libspi/remoteobject.h>
 
index 8ca561c..8aa5764 100644 (file)
@@ -212,7 +212,7 @@ _string_from_attribute_set (AtkAttributeSet *set)
       tmp = g_strdup_printf ("%s%s:%s%s",
                             ((GSList *)(set) == cur_attr) ? "" : " ",
                             at->name, at->value,
-                            (cur_attr->next) ? "" : "");
+                            (cur_attr->next) ? ";" : "");
       tmp2 = g_strconcat (attributes, tmp, NULL);
       g_free (tmp);
       g_free (attributes);
index 6812f5c..600c3d4 100644 (file)
@@ -82,6 +82,7 @@ typedef struct {
 typedef struct {
   CORBA_Object          object;
   SpiDeviceTypeCategory type;
+  Accessibility_EventTypeSeq    *typeseq;
 } DEControllerListener;
 
 typedef struct {
@@ -89,7 +90,6 @@ typedef struct {
 
   Accessibility_KeySet             *keys;
   Accessibility_ControllerEventMask mask;
-  Accessibility_KeyEventTypeSeq    *typeseq;
   Accessibility_EventListenerMode  *mode;      
 } DEControllerKeyListener;
 
@@ -98,6 +98,13 @@ typedef struct {
        unsigned int last_release_keycode;
        struct timeval last_press_time;
        struct timeval last_release_time;
+       int have_xkb;
+       int xkb_major_extension_opcode;
+       int xkb_base_event_code;
+       int xkb_base_error_code;
+       unsigned int xkb_latch_mask;
+       unsigned int pending_xkb_mod_relatch_mask;
+       XkbDescPtr xkb_desc;
 } DEControllerPrivateData;
 
 static void     spi_controller_register_with_devices          (SpiDEController           *controller);
@@ -108,10 +115,18 @@ static gboolean spi_controller_register_device_listener       (SpiDEController
                                                               CORBA_Environment         *ev);
 static void     spi_device_event_controller_forward_key_event (SpiDEController           *controller,
                                                               const XEvent              *event);
+static void     spi_deregister_controller_device_listener (SpiDEController            *controller,
+                                                          DEControllerListener *listener,
+                                                          CORBA_Environment          *ev);
 static void     spi_deregister_controller_key_listener (SpiDEController         *controller,
                                                        DEControllerKeyListener *key_listener,
                                                        CORBA_Environment       *ev);
+static gboolean spi_controller_notify_mouselisteners (SpiDEController                 *controller,
+                                                     const Accessibility_DeviceEvent *event,
+                                                     CORBA_Environment               *ev);
 
+static gboolean spi_eventtype_seq_contains_event (Accessibility_EventTypeSeq      *type_seq,
+                                                 const Accessibility_DeviceEvent *event);
 static gboolean spi_clear_error_state (void);
 static gboolean spi_dec_poll_mouse_moved (gpointer data);
 static gboolean spi_dec_poll_mouse_moving (gpointer data);
@@ -169,14 +184,17 @@ static gboolean
 spi_dec_poll_mouse_moved (gpointer data)
 {
   SpiRegistry *registry = SPI_REGISTRY (data);
+  SpiDEController *controller = registry->de_controller;
   CORBA_Environment ev;
   Accessibility_Event e;
+  Accessibility_DeviceEvent mouse_e;
   Window root_return, child_return;
   int win_x_return,win_y_return;
   int x, y;
   int poll_count_modulus = 10;
   unsigned int mask_return;
   gchar event_name[24];
+  gboolean is_consumed;
   Display *display = spi_get_display ();
 
   if (display != NULL)
@@ -211,14 +229,32 @@ spi_dec_poll_mouse_moved (gpointer data)
                                   button_number);
 #endif
                          snprintf (event_name, 22, "mouse:button:%dr", button_number);
+                         /* TODO: distinguish between physical and 
+                          * logical buttons 
+                          */
+                         mouse_e.type      = Accessibility_BUTTON_RELEASED_EVENT;
+                         mouse_e.id        = button_number;
+                         mouse_e.hw_code   = button_number;
+                          mouse_e.modifiers = (CORBA_unsigned_short) 
+                                              mouse_mask_state; 
+                         mouse_e.timestamp = 0;
+                         mouse_e.event_string = CORBA_string_dup ("");
+                         mouse_e.is_text   = CORBA_FALSE;
+                         is_consumed = 
+                           spi_controller_notify_mouselisteners (controller, 
+                                                                 &mouse_e, 
+                                                                 &ev);
+                         CORBA_free (mouse_e.event_string);
+
                          e.type = event_name;
                          e.source = BONOBO_OBJREF (registry->desktop);
                          e.detail1 = last_mouse_pos->x;
                          e.detail2 = last_mouse_pos->y;
                          CORBA_exception_init (&ev);
-                         Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
-                                                             &e,
-                                                             &ev);
+                         if (!is_consumed)
+                           Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                                               &e,
+                                                               &ev);  
                  }
          }
          if ((mask_return & key_modifier_mask) !=
@@ -315,7 +351,7 @@ spi_dec_init_mouse_listener (SpiRegistry *registry)
 
   if (display)
     {
-      XGrabButton (display, AnyButton, 0,
+      XGrabButton (display, AnyButton, AnyModifier,
                   gdk_x11_get_default_root_xwindow (),
                   True, ButtonPressMask | ButtonReleaseMask,
                   GrabModeSync, GrabModeAsync, None, None);
@@ -330,7 +366,7 @@ static DEControllerKeyListener *
 spi_dec_key_listener_new (CORBA_Object                            l,
                          const Accessibility_KeySet             *keys,
                          const Accessibility_ControllerEventMask mask,
-                         const Accessibility_KeyEventTypeSeq    *typeseq,
+                         const Accessibility_EventTypeSeq    *typeseq,
                          const Accessibility_EventListenerMode  *mode,
                          CORBA_Environment                      *ev)
 {
@@ -339,7 +375,7 @@ spi_dec_key_listener_new (CORBA_Object                            l,
   key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
   key_listener->keys = ORBit_copy_value (keys, TC_Accessibility_KeySet);
   key_listener->mask = mask;
-  key_listener->typeseq = ORBit_copy_value (typeseq, TC_Accessibility_KeyEventTypeSeq);
+  key_listener->listener.typeseq = ORBit_copy_value (typeseq, TC_Accessibility_EventTypeSeq);
   if (mode)
     key_listener->mode = ORBit_copy_value (mode, TC_Accessibility_EventListenerMode);
   else
@@ -356,6 +392,29 @@ spi_dec_key_listener_new (CORBA_Object                            l,
   return key_listener; 
 }
 
+static DEControllerListener *
+spi_dec_listener_new (CORBA_Object                            l,
+                     const Accessibility_EventTypeSeq    *typeseq,
+                     CORBA_Environment                      *ev)
+{
+  DEControllerListener *listener = g_new0 (DEControllerListener, 1);
+  listener->object = bonobo_object_dup_ref (l, ev);
+  listener->type = SPI_DEVICE_TYPE_MOUSE;
+  listener->typeseq = ORBit_copy_value (typeseq, TC_Accessibility_EventTypeSeq);
+  return listener;     
+}
+
+static DEControllerListener *
+spi_listener_clone (DEControllerListener *listener, CORBA_Environment *ev)
+{
+  DEControllerListener *clone = g_new0 (DEControllerListener, 1);
+  clone->object =
+         CORBA_Object_duplicate (listener->object, ev);
+  clone->type = listener->type;
+  clone->typeseq = ORBit_copy_value (listener->typeseq, TC_Accessibility_EventTypeSeq);
+  return clone;
+}
+
 static DEControllerKeyListener *
 spi_key_listener_clone (DEControllerKeyListener *key_listener, CORBA_Environment *ev)
 {
@@ -365,7 +424,7 @@ spi_key_listener_clone (DEControllerKeyListener *key_listener, CORBA_Environment
   clone->listener.type = SPI_DEVICE_TYPE_KBD;
   clone->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet);
   clone->mask = key_listener->mask;
-  clone->typeseq = ORBit_copy_value (key_listener->typeseq, TC_Accessibility_KeyEventTypeSeq);
+  clone->listener.typeseq = ORBit_copy_value (key_listener->listener.typeseq, TC_Accessibility_EventTypeSeq);
   if (key_listener->mode)
     clone->mode = ORBit_copy_value (key_listener->mode, TC_Accessibility_EventListenerMode);
   else
@@ -376,7 +435,7 @@ spi_key_listener_clone (DEControllerKeyListener *key_listener, CORBA_Environment
 static void
 spi_key_listener_data_free (DEControllerKeyListener *key_listener, CORBA_Environment *ev)
 {
-  CORBA_free (key_listener->typeseq);
+  CORBA_free (key_listener->listener.typeseq);
   CORBA_free (key_listener->keys);
   g_free (key_listener);
 }
@@ -389,11 +448,20 @@ spi_key_listener_clone_free (DEControllerKeyListener *clone, CORBA_Environment *
 }
 
 static void
-spi_dec_key_listener_free (DEControllerKeyListener *key_listener,
-                          CORBA_Environment       *ev)
+spi_listener_clone_free (DEControllerListener *clone, CORBA_Environment *ev)
+{
+  CORBA_Object_release (clone->object, ev);
+  CORBA_free (clone->typeseq);
+  g_free (clone);
+}
+
+static void
+spi_dec_listener_free (DEControllerListener    *listener,
+                      CORBA_Environment       *ev)
 {
-  bonobo_object_release_unref (key_listener->listener.object, ev);
-  spi_key_listener_data_free (key_listener, ev);
+  bonobo_object_release_unref (listener->object, ev);
+  if (listener->type == SPI_DEVICE_TYPE_KBD) 
+    spi_key_listener_data_free ((DEControllerKeyListener *) listener, ev);
 }
 
 static void
@@ -527,22 +595,109 @@ spi_controller_register_device_listener (SpiDEController      *controller,
       else
              return TRUE;
       break;
-    default:
+  case SPI_DEVICE_TYPE_MOUSE:
+      controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
+      break;
+  default:
+      fprintf (stderr, "WARNING: listener registration for unknown device type.\n");
       break;
   }
   return FALSE; 
 }
 
+static gboolean
+spi_controller_notify_mouselisteners (SpiDEController                 *controller,
+                                     const Accessibility_DeviceEvent *event,
+                                     CORBA_Environment               *ev)
+{
+  GList   *l;
+  GSList  *notify = NULL, *l2;
+  GList  **listeners = &controller->mouse_listeners;
+  gboolean is_consumed;
+
+  if (!listeners)
+    {
+      return FALSE;
+    }
+
+  for (l = *listeners; l; l = l->next)
+    {
+       DEControllerListener *listener = l->data;
+
+       if (spi_eventtype_seq_contains_event (listener->typeseq, event))
+         {
+           Accessibility_DeviceEventListener ls = listener->object;
+
+          if (ls != CORBA_OBJECT_NIL)
+            {
+              /* we clone (don't dup) the listener, to avoid refcount inc. */
+              notify = g_slist_prepend (notify,
+                                        spi_listener_clone (listener, ev));
+            }
+         }
+    }
+
+#ifdef SPI_KEYEVENT_DEBUG
+  if (!notify)
+    {
+      g_print ("no match for event\n");
+    }
+#endif
+
+  is_consumed = FALSE;
+  for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
+    {
+      DEControllerListener *listener = l2->data;           
+      Accessibility_DeviceEventListener ls = listener->object;
+
+      fprintf (stderr, "notifying mouse listener\n");
+      CORBA_exception_init (ev);
+      is_consumed = Accessibility_DeviceEventListener_notifyEvent (ls, event, ev);
+      fprintf (stderr, "%sconsumed\n", is_consumed ? "" : "not ");
+
+      if (BONOBO_EX (ev))
+        {
+          is_consumed = FALSE;
+         fprintf (stderr, "error notifying listener, removing it\n");
+         spi_deregister_controller_device_listener (controller, listener,
+                                                    ev);
+          CORBA_exception_free (ev);
+        }
+      
+      spi_listener_clone_free ((DEControllerListener *) l2->data, ev);
+    }
+
+  for (; l2; l2 = l2->next)
+    {
+      DEControllerListener *listener = l2->data;           
+      spi_listener_clone_free (listener, ev);
+      /* clone doesn't have its own ref, so don't use spi_device_listener_free */
+    }
+
+  g_slist_free (notify);
+
+#ifdef SPI_DEBUG
+  if (is_consumed) g_message ("consumed\n");
+#endif
+  return is_consumed;
+}
+
 static void
 spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
                                                 XEvent *xevent)
 {
   Accessibility_Event e;
+  Accessibility_DeviceEvent mouse_e;
   CORBA_Environment ev;
   gchar event_name[24];
-  int button = ((XButtonEvent *) xevent)->button;
+  gboolean is_consumed = FALSE;
+  gboolean xkb_mod_unlatch_occurred;
+  DEControllerPrivateData *priv;
+  XButtonEvent *xbutton_event = (XButtonEvent *) xevent;
+
+  int button = xbutton_event->button;
   
-  unsigned int mouse_button_state = ((XButtonEvent *) xevent)->state;
+  unsigned int mouse_button_state = xbutton_event->state;
 
   switch (button)
     {
@@ -567,23 +722,51 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
 
 #ifdef SPI_DEBUG  
   fprintf (stderr, "mouse button %d %s (%x)\n",
-          ((XButtonEvent *) xevent)->button, 
+          xbutton_event->button, 
           (xevent->type == ButtonPress) ? "Press" : "Release",
           mouse_button_state);
 #endif
   snprintf (event_name, 22, "mouse:button:%d%c", button,
            (xevent->type == ButtonPress) ? 'p' : 'r');
 
+  /* TODO: distinguish between physical and logical buttons */
+  mouse_e.type      = (xevent->type == ButtonPress) ? 
+                      Accessibility_BUTTON_PRESSED_EVENT :
+                      Accessibility_BUTTON_RELEASED_EVENT;
+  mouse_e.id        = button;
+  mouse_e.hw_code   = button;
+  mouse_e.modifiers = (CORBA_unsigned_short) xbutton_event->state;
+  mouse_e.timestamp = (CORBA_unsigned_long) xbutton_event->time;
+  mouse_e.event_string = CORBA_string_dup ("");
+  mouse_e.is_text   = CORBA_FALSE;
+  is_consumed = spi_controller_notify_mouselisteners (controller, &mouse_e, &ev);
+  CORBA_free (mouse_e.event_string);
+
   e.type = CORBA_string_dup (event_name);
   e.source = BONOBO_OBJREF (controller->registry->desktop);
   e.detail1 = last_mouse_pos->x;
   e.detail2 = last_mouse_pos->y;
   CORBA_exception_init (&ev);
+  
   Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
                                      &e,
                                      &ev);
+
+  xkb_mod_unlatch_occurred = (xevent->type == ButtonPress ||
+                             xevent->type == ButtonRelease);
   
-  XAllowEvents (spi_get_display (), ReplayPointer, CurrentTime);
+  /* if client wants to consume this event, and XKB latch state was
+   *   unset by this button event, we reset it
+   */
+  if (is_consumed && xkb_mod_unlatch_occurred)
+    {
+      priv = g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);            
+      priv->pending_xkb_mod_relatch_mask |= priv->xkb_latch_mask; 
+    }
+  
+  XAllowEvents (spi_get_display (),
+               (is_consumed) ? SyncPointer : ReplayPointer,
+               CurrentTime);
 }
 
 static GdkFilterReturn
@@ -591,19 +774,67 @@ global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
 {
   XEvent *xevent = gdk_xevent;
   SpiDEController *controller;
+  DEControllerPrivateData *priv;
+  Display *display = spi_get_display ();
+  controller = SPI_DEVICE_EVENT_CONTROLLER (data);
+  priv = (DEControllerPrivateData *)
+         g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);  
 
   if (xevent->type == KeyPress || xevent->type == KeyRelease)
     {
-      controller = SPI_DEVICE_EVENT_CONTROLLER (data);
       spi_device_event_controller_forward_key_event (controller, xevent);
-      /* FIXME: is this right ? */
       return GDK_FILTER_CONTINUE;
     }
   if (xevent->type == ButtonPress || xevent->type == ButtonRelease)
     {
-      controller = SPI_DEVICE_EVENT_CONTROLLER (data);
       spi_device_event_controller_forward_mouse_event (controller, xevent);
     }
+  if (xevent->type == priv->xkb_base_event_code)
+    {
+      XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent;
+
+      if (xkb_ev->xkb_type == XkbStateNotify)
+        {
+         XkbStateNotifyEvent *xkb_snev =
+                 (XkbStateNotifyEvent *) xkb_ev;
+         priv->xkb_latch_mask = xkb_snev->latched_mods;
+         if (priv->pending_xkb_mod_relatch_mask)
+           {
+             unsigned int feedback_mask;
+             fprintf (stderr, "relatching %x\n",
+                      priv->pending_xkb_mod_relatch_mask);
+             /* temporarily turn off the latch bell, if it's on */
+             XkbGetControls (display,
+                             XkbAccessXFeedbackMask,
+                             priv->xkb_desc);
+             feedback_mask = priv->xkb_desc->ctrls->ax_options;
+             if (feedback_mask & XkbAX_StickyKeysFBMask)
+             {
+               XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
+                                                0, False};      
+               priv->xkb_desc->ctrls->ax_options
+                             &= ~(XkbAX_StickyKeysFBMask);
+               XkbChangeControls (display, priv->xkb_desc, &changes);
+             }
+             XkbLatchModifiers (display,
+                                XkbUseCoreKbd,
+                                priv->pending_xkb_mod_relatch_mask,
+                                priv->pending_xkb_mod_relatch_mask);
+             if (feedback_mask & XkbAX_StickyKeysFBMask)
+             { 
+               XkbControlsChangesRec changes = {XkbAccessXFeedbackMask,
+                                                0, False};      
+               priv->xkb_desc->ctrls->ax_options = feedback_mask;
+               XkbChangeControls (display, priv->xkb_desc, &changes);
+             }
+             fprintf (stderr, "relatched %x\n",
+                      priv->pending_xkb_mod_relatch_mask);
+             priv->pending_xkb_mod_relatch_mask = 0;
+           }
+       }
+        else
+               fprintf (stderr, "XKB event %d\n", xkb_ev->xkb_type);
+    }
   
   return GDK_FILTER_CONTINUE;
 }
@@ -626,10 +857,25 @@ _spi_controller_device_error_handler (Display *display, XErrorEvent *error)
 static void
 spi_controller_register_with_devices (SpiDEController *controller)
 {
+  DEControllerPrivateData *priv = (DEControllerPrivateData *) 
+         g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);     
+
+  priv->xkb_desc = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd);
+
   /* calls to device-specific implementations and routines go here */
   /* register with: keyboard hardware code handler */
   /* register with: (translated) keystroke handler */
 
+  priv->have_xkb = XkbQueryExtension (spi_get_display (),
+                                     &priv->xkb_major_extension_opcode,
+                                     &priv->xkb_base_event_code,
+                                     &priv->xkb_base_error_code, NULL, NULL);
+  if (priv->have_xkb)
+    {
+      XkbSelectEvents (spi_get_display (),
+                      XkbUseCoreKbd,
+                      XkbStateNotifyMask, XkbStateNotifyMask);     
+    }  
   gdk_window_add_filter (NULL, global_filter_fn, controller);
 
   gdk_window_set_events (gdk_get_default_root_window (),
@@ -686,8 +932,8 @@ spi_key_set_contains_key (Accessibility_KeySet            *key_set,
 }
 
 static gboolean
-spi_key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq   *type_seq,
-                                     const Accessibility_DeviceEvent *key_event)
+spi_eventtype_seq_contains_event (Accessibility_EventTypeSeq      *type_seq,
+                                 const Accessibility_DeviceEvent *event)
 {
   gint i;
   gint len;
@@ -709,10 +955,10 @@ spi_key_eventtype_seq_contains_event (Accessibility_KeyEventTypeSeq   *type_seq,
   for (i = 0; i < len; ++i)
     {
 #ifdef SPI_DEBUG           
-      g_print ("type_seq[%d] = %d; key event type = %d\n", i,
-              (int) type_seq->_buffer[i], (int) key_event->type);
+      g_print ("type_seq[%d] = %d; event type = %d\n", i,
+              (int) type_seq->_buffer[i], (int) event->type);
 #endif      
-      if (type_seq->_buffer[i] == (CORBA_long) key_event->type)
+      if (type_seq->_buffer[i] == (CORBA_long) event->type)
         {
           return TRUE;
        }
@@ -728,7 +974,7 @@ spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event,
 {
   if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask & 0xFFFF)) &&
        spi_key_set_contains_key (listener->keys, key_event) &&
-       spi_key_eventtype_seq_contains_event (listener->typeseq, key_event) && 
+       spi_eventtype_seq_contains_event (listener->listener.typeseq, key_event) && 
       (is_system_global == listener->mode->global))
     {
       return TRUE;
@@ -795,14 +1041,14 @@ spi_controller_notify_keylisteners (SpiDEController                 *controller,
          CORBA_exception_free (ev);
         }
 
-      CORBA_Object_release (ls, ev);
+      spi_key_listener_clone_free (key_listener, ev);
     }
 
   for (; l2; l2 = l2->next)
     {
       DEControllerKeyListener *key_listener = l2->data;            
       spi_key_listener_clone_free (key_listener, ev);
-      /* clone doesn't have its own ref, so don't use spi_key_listener_free */
+      /* clone doesn't have its own ref, so don't use spi_dec_listener_free */
     }
 
   g_slist_free (notify);
@@ -1058,7 +1304,7 @@ static void
 spi_device_event_controller_object_finalize (GObject *object)
 {
   SpiDEController *controller;
-
+  DEControllerPrivateData *private;
   controller = SPI_DEVICE_EVENT_CONTROLLER (object);
 
 #ifdef SPI_DEBUG
@@ -1067,7 +1313,10 @@ spi_device_event_controller_object_finalize (GObject *object)
   /* disconnect any special listeners, get rid of outstanding keygrabs */
   XUngrabKey (spi_get_display (), AnyKey, AnyModifier, DefaultRootWindow (spi_get_display ()));
 
-  g_free (g_object_get_data (G_OBJECT (controller), "spi-dec-private"));
+  private = g_object_get_data (G_OBJECT (controller), "spi-dec-private");
+  if (private->xkb_desc)
+         XkbFreeKeyboard (private->xkb_desc, 0, True);
+  g_free (private);
   spi_device_event_controller_parent_class->finalize (object);
 }
 
@@ -1080,7 +1329,7 @@ impl_register_keystroke_listener (PortableServer_Servant                  servan
                                  const Accessibility_DeviceEventListener l,
                                  const Accessibility_KeySet             *keys,
                                  const Accessibility_ControllerEventMask mask,
-                                 const Accessibility_KeyEventTypeSeq    *type,
+                                 const Accessibility_EventTypeSeq       *type,
                                  const Accessibility_EventListenerMode  *mode,
                                  CORBA_Environment                      *ev)
 {
@@ -1097,23 +1346,42 @@ impl_register_keystroke_listener (PortableServer_Servant                  servan
 }
 
 
+/*
+ * CORBA Accessibility::DEController::registerDeviceEventListener
+ *     method implementation
+ */
+static CORBA_boolean
+impl_register_device_listener (PortableServer_Servant                  servant,
+                              const Accessibility_DeviceEventListener l,
+                              const Accessibility_EventTypeSeq       *event_types,
+                              CORBA_Environment                      *ev)
+{
+  SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER (
+         bonobo_object_from_servant (servant));
+  DEControllerListener *dec_listener;
+
+  dec_listener = spi_dec_listener_new (l, event_types, ev);
+  return spi_controller_register_device_listener (
+         controller, (DEControllerListener *) dec_listener, ev);
+}
+
 typedef struct {
        CORBA_Environment       *ev;
-       DEControllerKeyListener *key_listener;
-} RemoveKeyListenerClosure;
+       DEControllerListener    *listener;
+} RemoveListenerClosure;
 
 static SpiReEntrantContinue
-remove_key_listener_cb (GList * const *list,
-                       gpointer       user_data)
+remove_listener_cb (GList * const *list,
+                   gpointer       user_data)
 {
-  DEControllerKeyListener  *key_listener = (*list)->data;
-  RemoveKeyListenerClosure *ctx = user_data;
+  DEControllerListener  *listener = (*list)->data;
+  RemoveListenerClosure *ctx = user_data;
 
-  if (CORBA_Object_is_equivalent (ctx->key_listener->listener.object,
-                                 key_listener->listener.object, ctx->ev))
+  if (CORBA_Object_is_equivalent (ctx->listener->object,
+                                 listener->object, ctx->ev))
     {
       spi_re_entrant_list_delete_link (list);
-      spi_dec_key_listener_free (key_listener, ctx->ev);
+      spi_dec_listener_free (listener, ctx->ev);
     }
 
   return SPI_RE_ENTRANT_CONTINUE;
@@ -1124,29 +1392,39 @@ copy_key_listener_cb (GList * const *list,
                      gpointer       user_data)
 {
   DEControllerKeyListener  *key_listener = (*list)->data;
-  RemoveKeyListenerClosure *ctx = user_data;
+  RemoveListenerClosure    *ctx = user_data;
 
-  if (CORBA_Object_is_equivalent (ctx->key_listener->listener.object,
+  if (CORBA_Object_is_equivalent (ctx->listener->object,
                                  key_listener->listener.object, ctx->ev))
     {
       /* TODO: FIXME aggregate keys in case the listener is registered twice */
-      CORBA_free (ctx->key_listener->keys);        
-      ctx->key_listener->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet);
+      DEControllerKeyListener *ctx_key_listener = 
+       (DEControllerKeyListener *) ctx->listener; 
+      CORBA_free (ctx_key_listener->keys);         
+      ctx_key_listener->keys = ORBit_copy_value (key_listener->keys, TC_Accessibility_KeySet);
     }
 
   return SPI_RE_ENTRANT_CONTINUE;
 }
 
+static void
+spi_deregister_controller_device_listener (SpiDEController            *controller,
+                                          DEControllerListener *listener,
+                                          CORBA_Environment          *ev)
+{
+  spi_re_entrant_list_foreach (&controller->mouse_listeners,
+                              remove_listener_cb, listener);
+}
 
 static void
 spi_deregister_controller_key_listener (SpiDEController            *controller,
                                        DEControllerKeyListener    *key_listener,
                                        CORBA_Environment          *ev)
 {
-  RemoveKeyListenerClosure  ctx;
+  RemoveListenerClosure  ctx;
 
   ctx.ev = ev;
-  ctx.key_listener = key_listener;
+  ctx.listener = (DEControllerListener *) key_listener;
 
   /* special case, copy keyset from existing controller list entry */
   if (key_listener->keys->_length == 0) 
@@ -1158,7 +1436,7 @@ spi_deregister_controller_key_listener (SpiDEController            *controller,
   spi_controller_deregister_global_keygrabs (controller, key_listener);
 
   spi_re_entrant_list_foreach (&controller->key_listeners,
-                               remove_key_listener_cb, &ctx);
+                               remove_listener_cb, &ctx);
 
 }
 
@@ -1171,7 +1449,7 @@ impl_deregister_keystroke_listener (PortableServer_Servant                  serv
                                    const Accessibility_DeviceEventListener l,
                                    const Accessibility_KeySet             *keys,
                                    const Accessibility_ControllerEventMask mask,
-                                   const Accessibility_KeyEventTypeSeq    *type,
+                                   const Accessibility_EventTypeSeq       *type,
                                    CORBA_Environment                      *ev)
 {
   DEControllerKeyListener  *key_listener;
@@ -1188,29 +1466,50 @@ impl_deregister_keystroke_listener (PortableServer_Servant                  serv
 
   spi_deregister_controller_key_listener (controller, key_listener, ev);
 
-  spi_dec_key_listener_free (key_listener, ev);
+  spi_dec_listener_free ((DEControllerListener *) key_listener, ev);
+}
+
+/*
+ * CORBA Accessibility::DEController::deregisterDeviceEventListener
+ *     method implementation
+ */
+static void
+impl_deregister_device_listener (PortableServer_Servant                  servant,
+                                const Accessibility_DeviceEventListener l,
+                                const Accessibility_EventTypeSeq       *event_types,
+                                CORBA_Environment                      *ev)
+{
+  SpiDEController *controller;
+  DEControllerListener *listener = 
+          spi_dec_listener_new (l, event_types, ev);
+
+  controller = SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant));
+
+  spi_deregister_controller_device_listener (controller, listener, ev);
+
+  spi_dec_listener_free (listener, ev);
 }
 
 static unsigned int dec_xkb_get_slowkeys_delay (SpiDEController *controller)
 {
-       unsigned int retval = 0;
+  unsigned int retval = 0;
+  DEControllerPrivateData *priv = (DEControllerPrivateData *)
+         g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
 #ifdef HAVE_XKB
 #ifdef XKB_HAS_GET_SLOW_KEYS_DELAY     
-       retval = XkbGetSlowKeysDelay (spi_get_display (),
-                                     XkbUseCoreKbd, &bounce_delay);
+  retval = XkbGetSlowKeysDelay (spi_get_display (),
+                               XkbUseCoreKbd, &bounce_delay);
 #else
-       XkbDescPtr xkb = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd);
-       if (!(xkb == (XkbDescPtr) BadAlloc || xkb == NULL))
-       {
-               Status s = XkbGetControls (spi_get_display (),
-                                          XkbAllControlsMask, xkb);
-               if (s == Success)
-               {
-                       if (xkb->ctrls->enabled_ctrls & XkbSlowKeysMask)
-                               retval = xkb->ctrls->slow_keys_delay;
-               }
-               XkbFreeKeyboard (xkb, XkbAllControlsMask, True);
+  if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
+    {
+      Status s = XkbGetControls (spi_get_display (),
+                                XkbAllControlsMask, priv->xkb_desc);
+      if (s == Success)
+        {
+        if (priv->xkb_desc->ctrls->enabled_ctrls & XkbSlowKeysMask)
+                retval = priv->xkb_desc->ctrls->slow_keys_delay;
        }
+    }
 #endif
 #endif
 #ifdef SPI_XKB_DEBUG
@@ -1221,30 +1520,30 @@ static unsigned int dec_xkb_get_slowkeys_delay (SpiDEController *controller)
 
 static unsigned int dec_xkb_get_bouncekeys_delay (SpiDEController *controller)
 {
-       unsigned int retval = 0;
+  unsigned int retval = 0;
+  DEControllerPrivateData *priv = (DEControllerPrivateData *)
+         g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
 #ifdef HAVE_XKB
 #ifdef XKB_HAS_GET_BOUNCE_KEYS_DELAY   
-       retval = XkbGetBounceKeysDelay (spi_get_display (),
-                                       XkbUseCoreKbd, &bounce_delay);
+  retval = XkbGetBounceKeysDelay (spi_get_display (),
+                                 XkbUseCoreKbd, &bounce_delay);
 #else
-       XkbDescPtr xkb = XkbGetMap (spi_get_display (), 0, XkbUseCoreKbd);
-       if (!(xkb == (XkbDescPtr) BadAlloc || xkb == NULL))
-       {
-               Status s = XkbGetControls (spi_get_display (),
-                                          XkbAllControlsMask, xkb);
-               if (s == Success)
-               {
-                       if (xkb->ctrls->enabled_ctrls & XkbBounceKeysMask)
-                               retval = xkb->ctrls->debounce_delay;
-               }
-               XkbFreeKeyboard (xkb, XkbAllControlsMask, True);
+  if (!(priv->xkb_desc == (XkbDescPtr) BadAlloc || priv->xkb_desc == NULL))
+    {
+      Status s = XkbGetControls (spi_get_display (),
+                                XkbAllControlsMask, priv->xkb_desc);
+      if (s == Success)
+        {
+         if (priv->xkb_desc->ctrls->enabled_ctrls & XkbBounceKeysMask)
+                 retval = priv->xkb_desc->ctrls->debounce_delay;
        }
+    }
 #endif
 #endif
 #ifdef SPI_XKB_DEBUG
-       fprintf (stderr, "BounceKeys delay: %d\n", (int) retval);
+  fprintf (stderr, "BounceKeys delay: %d\n", (int) retval);
 #endif
-       return retval;
+  return retval;
 }
 
 static gboolean
@@ -1499,15 +1798,21 @@ spi_device_event_controller_class_init (SpiDEControllerClass *klass)
        
   epv->registerKeystrokeListener   = impl_register_keystroke_listener;
   epv->deregisterKeystrokeListener = impl_deregister_keystroke_listener;
+  epv->registerDeviceEventListener = impl_register_device_listener;
+  epv->deregisterDeviceEventListener = impl_deregister_device_listener;
   epv->generateKeyboardEvent       = impl_generate_keyboard_event;
   epv->generateMouseEvent          = impl_generate_mouse_event;
   epv->notifyListenersSync         = impl_notify_listeners_sync;
   epv->notifyListenersAsync        = impl_notify_listeners_async;
+
+  if (!spi_dec_private_quark)
+         spi_dec_private_quark = g_quark_from_static_string ("spi-dec-private");
 }
 
 static void
 spi_device_event_controller_init (SpiDEController *device_event_controller)
 {
+  DEControllerPrivateData *private;    
   device_event_controller->key_listeners   = NULL;
   device_event_controller->mouse_listeners = NULL;
   device_event_controller->keygrabs_list   = NULL;
@@ -1519,6 +1824,13 @@ spi_device_event_controller_init (SpiDEController *device_event_controller)
    */
   gdk_init (NULL, NULL);
   
+  private = g_new0 (DEControllerPrivateData, 1);
+  gettimeofday (&private->last_press_time, NULL);
+  gettimeofday (&private->last_release_time, NULL);
+  g_object_set_qdata (G_OBJECT (device_event_controller),
+                     spi_dec_private_quark,
+                     private);
+  
   spi_controller_register_with_devices (device_event_controller);
 }
 
@@ -1542,8 +1854,6 @@ spi_device_event_controller_forward_key_event (SpiDEController *controller,
   is_consumed = spi_controller_notify_keylisteners (
          controller, &key_event, CORBA_TRUE, &ev);
 
-  CORBA_exception_free (&ev);
-
   if (is_consumed)
     {
       XAllowEvents (spi_get_display (), AsyncKeyboard, CurrentTime);
@@ -1564,14 +1874,6 @@ spi_device_event_controller_new (SpiRegistry *registry)
   retval->registry = SPI_REGISTRY (bonobo_object_ref (
          BONOBO_OBJECT (registry)));
 
-  private = g_new0 (DEControllerPrivateData, 1);
-  gettimeofday (&private->last_press_time, NULL);
-  gettimeofday (&private->last_release_time, NULL);
-  if (!spi_dec_private_quark)
-         spi_dec_private_quark = g_quark_from_static_string ("spi-dec-private");
-  g_object_set_qdata (G_OBJECT (retval),
-                     spi_dec_private_quark,
-                     private);
   spi_dec_init_mouse_listener (registry);
   /* TODO: kill mouse listener on finalize */  
   return retval;
index 90ebb0d..14cb16f 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <bonobo/bonobo-object.h>
 #include <libspi/Accessibility.h>
-#include <libspi/keystrokelistener.h>
+#include <libspi/devicelistener.h>
 
 typedef struct _SpiDEController SpiDEController;
 
index 558f2df..c00365a 100644 (file)
@@ -631,7 +631,6 @@ impl_registry_notify_event (PortableServer_Servant     servant,
 
 }
 
-
 static void
 spi_registry_class_init (SpiRegistryClass *klass)
 {
index 5a06fda..bc2c579 100644 (file)
@@ -1,6 +1,6 @@
 NULL=
 
-noinst_PROGRAMS = test-simple at app simple-at stress-test keysynth-demo accessx-gui key-listener-test event-listener-test screen-review-test visual-bell
+noinst_PROGRAMS = test-simple at app simple-at stress-test keysynth-demo key-listener-test event-listener-test screen-review-test visual-bell
 
 key_listener_test_SOURCES = key-listener-test.c
 
@@ -20,8 +20,6 @@ simple_at_SOURCES = simple-at.c
 
 keysynth_demo_SOURCES = keysynth-demo.c 
 
-accessx_gui_SOURCES = accessx-gui.c 
-
 test_simple_SOURCES = test-simple.c 
 
 INCLUDES = -I$(top_srcdir)           \
index b22c89c..a729124 100644 (file)
@@ -30,10 +30,12 @@ static void traverse_accessible_tree (Accessible *accessible);
 static void report_event  (const AccessibleEvent *event, void *user_data);
 static void report_detail_event  (const AccessibleEvent *event, void *user_data);
 static void timing_test_event (const AccessibleEvent *event, void *user_data);
+static SPIBoolean report_mouse_event  (const AccessibleDeviceEvent *event, void *user_data);
 
 static AccessibleEventListener *generic_listener;
 static AccessibleEventListener *specific_listener;
 static AccessibleEventListener *test_listener;
+static AccessibleDeviceListener *mouse_device_listener;
 static gint n_elements_traversed = 0;
 static GTimer *timer;
 
@@ -86,6 +88,8 @@ main (int argc, char **argv)
          report_detail_event, NULL); 
   test_listener = SPI_createAccessibleEventListener (
          timing_test_event, NULL);
+  mouse_device_listener = SPI_createAccessibleDeviceListener (
+          report_mouse_event, NULL);
 
   SPI_registerGlobalEventListener (generic_listener,
                                   "focus:");
@@ -97,6 +101,9 @@ main (int argc, char **argv)
       SPI_registerGlobalEventListener (specific_listener,
                                       "mouse:abs");
   }
+  SPI_registerDeviceEventListener (mouse_device_listener, 
+                                  SPI_BUTTON_PRESSED | SPI_BUTTON_RELEASED,
+                                  NULL);
   SPI_registerGlobalEventListener (specific_listener,
                                   "keyboard:modifiers");
   SPI_registerGlobalEventListener (generic_listener,
@@ -255,6 +262,17 @@ report_detail_event (const AccessibleEvent *event, void *user_data)
   if (s) SPI_freeString (s);
 }
 
+SPIBoolean
+report_mouse_event (const AccessibleDeviceEvent *event, void *user_data)
+{
+  fprintf (stderr, "mouse event %ld %d %x %x\n", 
+          event->keyID, 
+          (int) event->keycode,
+          (unsigned) event->type,
+          (unsigned) event->modifiers);
+  return FALSE;
+}
+
 void
 timing_test_event (const AccessibleEvent *event, void *user_data)
 {
index dc0186a..e09942a 100644 (file)
@@ -49,7 +49,7 @@ static AccessibleKeySet            *tab_keyset;
 int
 main (int argc, char **argv)
 {
-  char *tab_strings[1];
+  const char *tab_strings[1] = {"Tab"};
   short keycodes[] = {65, 64, 23};
   SPIBoolean retval = FALSE;
        
@@ -65,7 +65,6 @@ main (int argc, char **argv)
   command_keyset = SPI_createAccessibleKeySet (1, "q", NULL, NULL);
   async_keyset = SPI_createAccessibleKeySet (3, NULL, keycodes, NULL);
   sync_keyset = SPI_createAccessibleKeySet (3, "def", NULL, NULL);
-  tab_strings[0] = "Tab";
   tab_keyset = SPI_createAccessibleKeySet (1,  NULL, NULL, tab_strings);
   retval = SPI_registerAccessibleKeystrokeListener(command_key_listener,
                                          command_keyset,
index f5b4158..720773c 100644 (file)
@@ -171,7 +171,6 @@ increment_scan (gpointer data)
       case SCAN_LINES_DONE:
       case SCAN_KEYS_DONE:
          return FALSE;
-      default:
     }
   return TRUE;
 }
index 802a3d0..2d13812 100644 (file)
@@ -129,7 +129,7 @@ create_test_window (void)
                                           GTK_ICON_SIZE_LARGE_TOOLBAR);
        test_window_add_and_show (GTK_CONTAINER (vbox), widget);
 
-       widget = g_object_new (GTK_TYPE_RANGE, NULL);
+       widget = g_object_new (GTK_TYPE_HSCALE, NULL);
        gtk_range_set_range (GTK_RANGE (widget), 0.0, 100.0);
        test_window_add_and_show (GTK_CONTAINER (vbox), widget);
 
@@ -157,8 +157,8 @@ test_roles (void)
        for (i = -1; i < 1000; i++)
                g_assert (AccessibleRole_getName (i) != NULL);
 
-       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_FILE_CHOOSER), "file chooser"));
-       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_RADIO_BUTTON), "radiobutton"));
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_FILE_CHOOSER), "file-chooser"));
+       g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_RADIO_BUTTON), "radio-button"));
        g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_TABLE), "table"));
        g_assert (!strcmp (AccessibleRole_getName (SPI_ROLE_WINDOW), "window"));
 }
@@ -692,7 +692,6 @@ key_listener_cb (const AccessibleKeystroke *stroke,
 static void
 test_keylisteners (void)
 {
-#ifdef BILL_MAKES_THIS_WORK_RELIABLY
        int i;
        AccessibleKeystroke stroke;
        AccessibleKeystrokeListener *key_listener;
@@ -704,7 +703,7 @@ test_keylisteners (void)
                key_listener_cb, &stroke);
 
        test_keyset = SPI_createAccessibleKeySet (1, "=", NULL, NULL);
-       
+
        g_assert (SPI_registerAccessibleKeystrokeListener (
                key_listener,
                test_keyset,
@@ -736,7 +735,6 @@ test_keylisteners (void)
         g_assert (SPI_generateMouseEvent (-50, -50, "rel"));             
         g_assert (SPI_generateMouseEvent (-50, -50, "rel"));             
         g_assert (SPI_generateMouseEvent (-1, -1, "b1c")); 
-#endif
 }
 
 int
@@ -771,6 +769,7 @@ main (int argc, char **argv)
        win = create_test_window ();
 
        global_listener = SPI_createAccessibleEventListener (global_listener_cb, win);
+
        g_assert (SPI_registerGlobalEventListener (global_listener, "focus:"));
 
        fprintf (stderr, "Waiting for focus event ...\n");
index 874a4bc..d8d0f59 100755 (executable)
@@ -138,7 +138,6 @@ int main (int argc, char **argv)
                                /* flash something */
                                visual_bell_notify (xkb_ev);
                                break;
-                       default:
                        }
                }
        }