Added docs and C bindings for AccessibleStateSet and AccessibleRelationSet.
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 18 Nov 2001 22:51:50 +0000 (22:51 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Sun, 18 Nov 2001 22:51:50 +0000 (22:51 +0000)
Improved listener API docs and listed legal signals (other than GTK+ signals,
which are documented in GTK+ itself).
C bindings documentation coverage is now 100%.
Changed Registry.idl slightly, added two methods to DeviceEventController API.
Some work towards non-preemptive key listeners.
Fixed regression in signal connection caused by changes to Gtk+.
Connected bridge to all signals, so they should be available if they are emitted.

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

14 files changed:
ChangeLog
at-bridge/bridge.c
atk-bridge/bridge.c
cspi/spi-listener.h
cspi/spi.h
cspi/spi_accessible.c
cspi/spi_registry.c
docs/at-spi-sections.txt
idl/Accessibility_Registry.idl
idl/Registry.idl
libspi/deviceeventcontroller.c
libspi/registry.c
registryd/deviceeventcontroller.c
registryd/registry.c

index c523582..032a7db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,73 @@
+2001-18-11  Bill Haneman <bill.haneman@sun.com>
+
+       * libspi/spi_accessible.c: Added docs and C bindings for
+       AccessibleStateSet. (No implementations yet).  Documentation
+       coverage for C bindings now 100%. Made docs for event listeners
+       more explicit.
+       
+       * idl/Registry.idl:
+       Added methods 
+            boolean notifyListenersSync (in DeviceEventListener listener,
+                                    in DeviceEvent event);
+
+            oneway void notifyListenersAsync (in DeviceEventListener listener,
+                                         in DeviceEvent event);
+
+       Added DeviceEventListener and DeviceEvent structs (may deprecate
+       KeyStroke and KeystrokeListener in favor of this generic
+       event/listener framework for devices).
+
+       * libspi/deviceeventcontroller.c:
+
+       Changed some key listener code to take masks, etc., and paved the
+       way for integration of toolkit/non-preemptive key events. Changed
+       signatures of some internal methods.
+
+       * at-bridge/bridge.c:
+        Fixed regression connecting to interface signals, apparently
+       caused by GTK+ changes.
+
+       Added an internal bridge_state_listener to deal with
+       property-change:accessible-state signals.
+
+       Changed the key_listeners GList to store structs (including masks,
+       etc.) instead of just CORBA_Objects (required for full
+       implementation of key listener API).
+
+       Connected the bridge to all currently supported Atk signals.
+       Events now supported: 
+           object:property-change
+            object:property-change:accessible-name
+            object:property-change:accessible-state
+            object:property-change:accessible-description
+            object:property-change:accessible-parent
+            object:property-change:accessible-value
+            object:property-change:accessible-role
+            object:property-change:accessible-table-caption
+            object:property-change:accessible-table-column-description
+            object:property-change:accessible-table-column-header
+            object:property-change:accessible-table-row-description
+            object:property-change:accessible-table-row-header
+            object:property-change:accessible-table-summary
+            object:children-changed
+            object:visible-data-changed
+            object:selection-changed
+            object:text-selection-changed
+            object:text-changed
+            object:text-caret-moved
+            object:row-inserted
+            object:row-reordered
+            object:row-deleted
+            object:column-inserted
+            object:column-reordered
+            object:column-deleted
+            object:model-changed        
+
 2001-16-11  Bill Haneman <bill.haneman@sun.com>
 
 2001-16-11  Bill Haneman <bill.haneman@sun.com>
 
+       * libspi/hyperlink.c,h:
+       Fixed some broken stuff in hyperlink.
+       
        * libspi/relation.h:
        * libspi/relation.c:
        * cspi/spi_accessible.c:
        * libspi/relation.h:
        * libspi/relation.c:
        * cspi/spi_accessible.c:
index 2d988ee..6c66892 100644 (file)
@@ -26,6 +26,7 @@
 #include <orbit/orbit.h>
 #include <atk/atk.h>
 #include <atk/atkobject.h>
 #include <orbit/orbit.h>
 #include <atk/atk.h>
 #include <atk/atkobject.h>
+#include <atk/atknoopobject.h>
 #include <libspi/Accessibility.h>
 #include "accessible.h"
 #include "application.h"
 #include <libspi/Accessibility.h>
 #include "accessible.h"
 #include "application.h"
@@ -54,6 +55,10 @@ static gboolean bridge_property_event_listener (GSignalInvocationHint *signal_hi
                                                guint n_param_values,
                                                const GValue *param_values,
                                                gpointer data);
                                                guint n_param_values,
                                                const GValue *param_values,
                                                gpointer data);
+static gboolean bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+                                            guint n_param_values,
+                                            const GValue *param_values,
+                                            gpointer data);
 static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
                                        guint n_param_values,
                                        const GValue *param_values,
 static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
                                        guint n_param_values,
                                        const GValue *param_values,
@@ -125,19 +130,27 @@ bridge_register_app (gpointer gp)
 static void
 register_atk_event_listeners ()
 {
 static void
 register_atk_event_listeners ()
 {
-  /* Register for focus event notifications, and register app with central registry  */
+  GType t;
+
+  /*
+   * kludge to make sure the Atk interface types are registered, otherwise
+   * the AtkText signal handlers below won't get registered
+   */
 
 
-/* kludge to make sure the Atk interface types are registered, otherwise
-   the AtkText signal handlers below won't get registered */
+  AtkNoOpObject *o = atk_no_op_object_new (g_object_new (ATK_TYPE_OBJECT, NULL));
+
+  /* Register for focus event notifications, and register app with central registry  */
 
 
-  ATK_TYPE_TEXT;
+  g_type_class_ref (ATK_TYPE_TEXT);
+  g_type_class_ref (ATK_TYPE_SELECTION);
+  g_type_class_ref (ATK_TYPE_TABLE);
 
   atk_add_focus_tracker (bridge_focus_tracker);
   atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
 
   atk_add_focus_tracker (bridge_focus_tracker);
   atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
-  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:model-changed");
-  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:selection-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkSelection:selection-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-selection-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
@@ -146,6 +159,7 @@ register_atk_event_listeners ()
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:model-changed");
   atk_add_key_event_listener    (bridge_key_listener, NULL);
 }
 
   atk_add_key_event_listener    (bridge_key_listener, NULL);
 }
 
@@ -219,10 +233,68 @@ bridge_property_event_listener (GSignalInvocationHint *signal_hint,
   return TRUE;
 }
 
   return TRUE;
 }
 
+static gboolean
+bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+                            guint n_param_values,
+                            const GValue *param_values,
+                            gpointer data)
+{
+  Accessibility_Event *e = Accessibility_Event__alloc();
+  Bonobo_Unknown source = NULL;
+  AtkObject *aobject;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (state) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+  values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+    g_object_unref (G_OBJECT(aobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+  
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:%s:%s", values->property_name, "?");
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
+  e->detail1 = (unsigned long) values->old_value.data[0].v_ulong;
+  e->detail2 = (unsigned long) values->new_value.data[0].v_ulong;
+  if (source)
+    Accessibility_Registry_notifyEvent (registry, e, &ev);
+  return TRUE;
+}
+
 static gint
 bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
 {
 static gint
 bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
 {
-  g_print ("bridge key listener!\n");
+  Accessibility_KeyStroke *key_event;
+  static Accessibility_DeviceEventController controller = CORBA_OBJECT_NIL;
+  if (controller == CORBA_OBJECT_NIL)
+    {
+      controller = Accessibility_Registry_getDeviceEventController (registry, &ev);
+    }
+  g_print ("bridge key listener fired!\n");
+/* Accessibility_DeviceEventController_notifyListenersSync (controller, key_event, &ev); */
 }
 
 static gboolean
 }
 
 static gboolean
@@ -243,7 +315,7 @@ bridge_signal_listener (GSignalInvocationHint *signal_hint,
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
 #ifdef SPI_BRIDGE_DEBUG
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
 #ifdef SPI_BRIDGE_DEBUG
-  fprintf (stderr, "Received (property) signal %s:%s\n",
+  fprintf (stderr, "Received signal %s:%s\n",
           g_type_name (signal_query.itype), name);
 #endif
   gobject = g_value_get_object (param_values + 0);
           g_type_name (signal_query.itype), name);
 #endif
   gobject = g_value_get_object (param_values + 0);
index 2d988ee..6c66892 100644 (file)
@@ -26,6 +26,7 @@
 #include <orbit/orbit.h>
 #include <atk/atk.h>
 #include <atk/atkobject.h>
 #include <orbit/orbit.h>
 #include <atk/atk.h>
 #include <atk/atkobject.h>
+#include <atk/atknoopobject.h>
 #include <libspi/Accessibility.h>
 #include "accessible.h"
 #include "application.h"
 #include <libspi/Accessibility.h>
 #include "accessible.h"
 #include "application.h"
@@ -54,6 +55,10 @@ static gboolean bridge_property_event_listener (GSignalInvocationHint *signal_hi
                                                guint n_param_values,
                                                const GValue *param_values,
                                                gpointer data);
                                                guint n_param_values,
                                                const GValue *param_values,
                                                gpointer data);
+static gboolean bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+                                            guint n_param_values,
+                                            const GValue *param_values,
+                                            gpointer data);
 static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
                                        guint n_param_values,
                                        const GValue *param_values,
 static gboolean bridge_signal_listener (GSignalInvocationHint *signal_hint,
                                        guint n_param_values,
                                        const GValue *param_values,
@@ -125,19 +130,27 @@ bridge_register_app (gpointer gp)
 static void
 register_atk_event_listeners ()
 {
 static void
 register_atk_event_listeners ()
 {
-  /* Register for focus event notifications, and register app with central registry  */
+  GType t;
+
+  /*
+   * kludge to make sure the Atk interface types are registered, otherwise
+   * the AtkText signal handlers below won't get registered
+   */
 
 
-/* kludge to make sure the Atk interface types are registered, otherwise
-   the AtkText signal handlers below won't get registered */
+  AtkNoOpObject *o = atk_no_op_object_new (g_object_new (ATK_TYPE_OBJECT, NULL));
+
+  /* Register for focus event notifications, and register app with central registry  */
 
 
-  ATK_TYPE_TEXT;
+  g_type_class_ref (ATK_TYPE_TEXT);
+  g_type_class_ref (ATK_TYPE_SELECTION);
+  g_type_class_ref (ATK_TYPE_TABLE);
 
   atk_add_focus_tracker (bridge_focus_tracker);
   atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
 
   atk_add_focus_tracker (bridge_focus_tracker);
   atk_add_global_event_listener (bridge_property_event_listener, "Gtk:AtkObject:property-change");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:children-changed");
-  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:model-changed");
-  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:selection-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkObject:visible-data-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkSelection:selection-changed");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-selection-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-changed");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkText:text-caret-moved");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:row-inserted");
@@ -146,6 +159,7 @@ register_atk_event_listeners ()
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-inserted");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-reordered");
   atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:column-deleted");
+  atk_add_global_event_listener (bridge_signal_listener, "Gtk:AtkTable:model-changed");
   atk_add_key_event_listener    (bridge_key_listener, NULL);
 }
 
   atk_add_key_event_listener    (bridge_key_listener, NULL);
 }
 
@@ -219,10 +233,68 @@ bridge_property_event_listener (GSignalInvocationHint *signal_hint,
   return TRUE;
 }
 
   return TRUE;
 }
 
+static gboolean
+bridge_state_event_listener (GSignalInvocationHint *signal_hint,
+                            guint n_param_values,
+                            const GValue *param_values,
+                            gpointer data)
+{
+  Accessibility_Event *e = Accessibility_Event__alloc();
+  Bonobo_Unknown source = NULL;
+  AtkObject *aobject;
+  AtkPropertyValues *values;
+  GObject *gobject;
+  GSignalQuery signal_query;
+  gchar *name;
+  char sbuf[APP_STATIC_BUFF_SZ];
+  
+  g_signal_query (signal_hint->signal_id, &signal_query);
+  name = signal_query.signal_name;
+#ifdef SPI_BRIDGE_DEBUG
+  fprintf (stderr, "Received (state) signal %s:%s\n",
+          g_type_name (signal_query.itype), name);
+#endif
+  gobject = g_value_get_object (param_values + 0);
+  values = (AtkPropertyValues*) g_value_get_pointer (param_values + 1);
+
+  /* notify the actual listeners */
+  if (ATK_IS_IMPLEMENTOR (gobject))
+  {
+    aobject = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (gobject));
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+    g_object_unref (G_OBJECT(aobject));
+  }
+  else if (ATK_IS_OBJECT (gobject))
+  {
+    aobject = ATK_OBJECT (gobject);
+    source = CORBA_Object_duplicate (BONOBO_OBJREF (spi_accessible_new (aobject)), &ev);
+  }
+  else
+  {
+    g_error("received property-change event from non-AtkImplementor");
+  }
+  
+  snprintf(sbuf, APP_STATIC_BUFF_SZ, "object:%s:%s", values->property_name, "?");
+  e->type = CORBA_string_dup (sbuf);
+  e->source = source;
+  e->detail1 = (unsigned long) values->old_value.data[0].v_ulong;
+  e->detail2 = (unsigned long) values->new_value.data[0].v_ulong;
+  if (source)
+    Accessibility_Registry_notifyEvent (registry, e, &ev);
+  return TRUE;
+}
+
 static gint
 bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
 {
 static gint
 bridge_key_listener (AtkImplementor *atk_impl, AtkKeyEventStruct *event, gpointer data)
 {
-  g_print ("bridge key listener!\n");
+  Accessibility_KeyStroke *key_event;
+  static Accessibility_DeviceEventController controller = CORBA_OBJECT_NIL;
+  if (controller == CORBA_OBJECT_NIL)
+    {
+      controller = Accessibility_Registry_getDeviceEventController (registry, &ev);
+    }
+  g_print ("bridge key listener fired!\n");
+/* Accessibility_DeviceEventController_notifyListenersSync (controller, key_event, &ev); */
 }
 
 static gboolean
 }
 
 static gboolean
@@ -243,7 +315,7 @@ bridge_signal_listener (GSignalInvocationHint *signal_hint,
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
 #ifdef SPI_BRIDGE_DEBUG
   g_signal_query (signal_hint->signal_id, &signal_query);
   name = signal_query.signal_name;
 #ifdef SPI_BRIDGE_DEBUG
-  fprintf (stderr, "Received (property) signal %s:%s\n",
+  fprintf (stderr, "Received signal %s:%s\n",
           g_type_name (signal_query.itype), name);
 #endif
   gobject = g_value_get_object (param_values + 0);
           g_type_name (signal_query.itype), name);
 #endif
   gobject = g_value_get_object (param_values + 0);
index 678ad55..ec8b265 100644 (file)
@@ -9,9 +9,6 @@ extern "C" {
 #include "accessibleeventlistener.h"
 #include "keystrokelistener.h"
 
 #include "accessibleeventlistener.h"
 #include "keystrokelistener.h"
 
-#define SPI_KEYSET_ALL_KEYS ((void *)NULL)
-
-
 /*
  *
  * Structure used to encapsulate event information
 /*
  *
  * Structure used to encapsulate event information
index 1a7dc53..b29719e 100644 (file)
@@ -111,7 +111,7 @@ typedef struct _AccessibleKeySet
  * @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
  *                       includes all keycodes and keyvals for the specified modifier set.
  **/
  * @SPI_KEYSET_ALL_KEYS: A special value for an AccessibleKeySet type, which tacitly
  *                       includes all keycodes and keyvals for the specified modifier set.
  **/
-#define SPI_KEYSET_ALL_KEYS ((void *)NULL)
+#define SPI_KEYSET_ALL_KEYS NULL
 
 typedef unsigned long AccessibleKeyMaskType;
 
 
 typedef unsigned long AccessibleKeyMaskType;
 
index bdeef1f..31fb819 100644 (file)
@@ -809,3 +809,157 @@ AccessibleRelation_getTarget (AccessibleRelation *obj, int i)
 {
   return NULL;
 }
 {
   return NULL;
 }
+
+/**
+ * AccessibleStateSet_ref:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Increment the reference count for an #AccessibleStateSet object.
+ *
+ * Returns: (no return code implemented yet).
+ *
+ **/
+int
+AccessibleStateSet_ref (AccessibleStateSet *obj)
+{
+/*  Accessibility_StateSet_ref (*obj, &ev); */
+  spi_check_ev (&ev, "ref");
+  return 0;
+}
+
+/**
+ * AccessibleStateSet_unref:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Decrement the reference count for an #AccessibleStateSet object.
+ *
+ * Returns: (no return code implemented yet).
+ *
+ **/
+int
+AccessibleStateSet_unref (AccessibleStateSet *obj)
+{
+/*  Accessibility_StateSet_unref (*obj, &ev); */
+  spi_check_ev (&ev, "unref");
+  return 0;
+}
+
+
+/**
+ * AccessibleStateSet_contains:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState for which the specified #AccessibleStateSet
+ *       will be queried.
+ *
+ * Determine whether a given #AccessibleStateSet includes a given state; that is,
+ *       whether @state is true for the stateset in question.
+ *
+ * Returns: #TRUE if @state is true/included in the given #AccessibleStateSet,
+ *          otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_contains (AccessibleStateSet *obj,
+                            AccessibleState state)
+{
+  CORBA_boolean retval = Accessibility_StateSet_contains (*obj, state, &ev);
+  spi_check_ev (&ev, "contains");
+  return (boolean) retval;
+}
+
+/**
+ * AccessibleStateSet_add:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState to be added to the specified #AccessibleStateSet
+ *
+ * Add a particular #AccessibleState to an #AccessibleStateSet (i.e. set the
+ *       given state to #TRUE in the stateset.
+ *
+ **/
+void
+AccessibleStateSet_add (AccessibleStateSet *obj,
+                       AccessibleState state)
+{
+  Accessibility_StateSet_add (*obj, state, &ev);
+  spi_check_ev (&ev, "contains");
+}
+
+
+/**
+ * AccessibleStateSet_remove:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ * @state: an #AccessibleState to be removed from the specified #AccessibleStateSet
+ *
+ * Remove a particular #AccessibleState to an #AccessibleStateSet (i.e. set the
+ *       given state to #FALSE in the stateset.)
+ *
+ **/
+void
+AccessibleStateSet_remove (AccessibleStateSet *obj,
+                          AccessibleState state)
+{
+  Accessibility_StateSet_remove (*obj, state, &ev);
+  spi_check_ev (&ev, "contains");
+}
+
+/**
+ * AccessibleStateSet_equals:
+ * @obj: a pointer to the first #AccessibleStateSet object on which to operate.
+ * @obj2: a pointer to the second #AccessibleStateSet object on which to operate.
+ *
+ * Determine whether two instances of #AccessibleStateSet are equivalent (i.e.
+ *         consist of the same #AccessibleStates).  Useful for checking multiple
+ *         state variables at once; construct the target state then compare against it.
+ *
+ * @see AccessibleStateSet_compare().
+ *
+ * Returns: #TRUE if the two #AccessibleStateSets are equivalent,
+ *          otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_equals (AccessibleStateSet *obj,
+                           AccessibleStateSet *obj2)
+{
+  return Accessibility_StateSet_equals (*obj, *obj2, &ev);
+}
+
+/**
+ * AccessibleStateSet_compare:
+ * @obj: a pointer to the first #AccessibleStateSet object on which to operate.
+ * @obj2: a pointer to the second #AccessibleStateSet object on which to operate.
+ *
+ * Determine the differences between two instances of #AccessibleStateSet.
+ *.
+ * @see AccessibleStateSet_equals().
+ *
+ * Returns: an #AccessibleStateSet object containing all states contained on one of
+ *          the two sets but not the other.
+ *
+ **/
+void
+AccessibleStateSet_compare (AccessibleStateSet *obj,
+                            AccessibleStateSet *obj2,
+                            AccessibleStateSet **differenceSet);
+
+
+/**
+ * AccessibleStateSet_isEmpty:
+ * @obj: a pointer to the #AccessibleStateSet object on which to operate.
+ *
+ * Determine whether a given #AccessibleStateSet is the empty set.
+ *
+ * Returns: #TRUE if the given #AccessibleStateSet contains no (true) states,
+ *          otherwise #FALSE.
+ *
+ **/
+boolean
+AccessibleStateSet_isEmpty (AccessibleStateSet *obj)
+{
+  return TRUE; 
+  /*  return Accessibility_StateSet_isEmpty (*obj, &ev);*/
+}
+
+
+
+
index 72f9314..40f81b7 100644 (file)
@@ -17,10 +17,44 @@ static Display *display = NULL;
  *            notification is requested.  Format is
  *            EventClass:major_type:minor_type:detail
  *            where all subfields other than EventClass are optional.
  *            notification is requested.  Format is
  *            EventClass:major_type:minor_type:detail
  *            where all subfields other than EventClass are optional.
- *            EventClasses include "Focus", "Window", "Mouse",
+ *            EventClasses include "object", "window", "mouse",
  *            and toolkit events (e.g. "Gtk", "AWT").
  *            Examples: "focus:", "Gtk:GtkWidget:button_press_event".
  *
  *            and toolkit events (e.g. "Gtk", "AWT").
  *            Examples: "focus:", "Gtk:GtkWidget:button_press_event".
  *
+ * Legal object event types:
+ *
+ *    (property change events)
+ *
+ *            object:property-change
+ *            object:property-change:accessible-name
+ *            object:property-change:accessible-state
+ *            object:property-change:accessible-description
+ *            object:property-change:accessible-parent
+ *            object:property-change:accessible-value
+ *            object:property-change:accessible-role
+ *            object:property-change:accessible-table-caption
+ *            object:property-change:accessible-table-column-description
+ *            object:property-change:accessible-table-column-header
+ *            object:property-change:accessible-table-row-description
+ *            object:property-change:accessible-table-row-header
+ *            object:property-change:accessible-table-summary
+ *
+ *    (other object events)
+ *
+ *            object:children-changed
+ *            object:visible-data-changed
+ *            object:selection-changed
+ *            object:text-selection-changed
+ *            object:text-changed
+ *            object:text-caret-moved
+ *            object:row-inserted
+ *            object:row-reordered
+ *            object:row-deleted
+ *            object:column-inserted
+ *            object:column-reordered
+ *            object:column-deleted
+ *            object:model-changed
+ *
  * NOTE: this string may be UTF-8, but should not contain byte value 56
  *            (ascii ':'), except as a delimiter, since non-UTF-8 string
  *            delimiting functions are used internally.
  * NOTE: this string may be UTF-8, but should not contain byte value 56
  *            (ascii ':'), except as a delimiter, since non-UTF-8 string
  *            delimiting functions are used internally.
index 2eeaa9b..a6bdd0e 100644 (file)
@@ -31,7 +31,6 @@ AccessibleKeyEventMask
 AccessibleKeyMaskType
 AccessibleKeyEventType
 AccessibleKeyListenerSyncType
 AccessibleKeyMaskType
 AccessibleKeyEventType
 AccessibleKeyListenerSyncType
-SPI_KEYSET_ALL_KEYS
 createAccessibleKeystrokeListener
 registerGlobalEventListener
 deregisterGlobalEventListener
 createAccessibleKeystrokeListener
 registerGlobalEventListener
 deregisterGlobalEventListener
index 5908106..2e56cf3 100644 (file)
@@ -157,6 +157,11 @@ module Accessibility {
     KEY_RELEASED
   };
 
     KEY_RELEASED
   };
 
+  enum EventType {
+    KEY_PRESSED_EVENT,
+    KEY_RELEASED_EVENT
+  };
+
   enum KeySynthType {
     KEY_PRESS,
     KEY_RELEASE,
   enum KeySynthType {
     KEY_PRESS,
     KEY_RELEASE,
@@ -183,10 +188,19 @@ module Accessibility {
   struct KeyStroke {
     long keyID;
     short keycode;
   struct KeyStroke {
     long keyID;
     short keycode;
+    unsigned long timestamp;
     KeyEventType type; 
     unsigned short modifiers;
   };
 
     KeyEventType type; 
     unsigned short modifiers;
   };
 
+  struct DeviceEvent {
+    long eventID;
+    short hw_code;
+    unsigned long timestamp;
+    EventType type; 
+    unsigned short modifiers;
+  };
+
   typedef sequence< long > KeySet;
   typedef sequence< KeyEventType > KeyEventTypeSeq;
 
   typedef sequence< long > KeySet;
   typedef sequence< KeyEventType > KeyEventTypeSeq;
 
@@ -194,6 +208,10 @@ module Accessibility {
         boolean keyEvent (in KeyStroke key);
   };
 
         boolean keyEvent (in KeyStroke key);
   };
 
+  interface DeviceEventListener : Bonobo::Unknown {
+        boolean notifyEvent (in DeviceEvent event);
+  };
+
   interface DeviceEventController : Bonobo::Unknown {
 
        /**
   interface DeviceEventController : Bonobo::Unknown {
 
        /**
@@ -239,6 +257,12 @@ module Accessibility {
                                        in KeyEventTypeSeq type,
                                        in boolean is_synchronous);
     
                                        in KeyEventTypeSeq type,
                                        in boolean is_synchronous);
     
+        boolean notifyListenersSync (in DeviceEventListener listener,
+                                    in DeviceEvent event);
+
+        oneway void notifyListenersAsync (in DeviceEventListener listener,
+                                         in DeviceEvent event);
+
         /**
          * generateKeyEvent:
          * @keycode: a long integer indicating the keycode of
         /**
          * generateKeyEvent:
          * @keycode: a long integer indicating the keycode of
index 5908106..2e56cf3 100644 (file)
@@ -157,6 +157,11 @@ module Accessibility {
     KEY_RELEASED
   };
 
     KEY_RELEASED
   };
 
+  enum EventType {
+    KEY_PRESSED_EVENT,
+    KEY_RELEASED_EVENT
+  };
+
   enum KeySynthType {
     KEY_PRESS,
     KEY_RELEASE,
   enum KeySynthType {
     KEY_PRESS,
     KEY_RELEASE,
@@ -183,10 +188,19 @@ module Accessibility {
   struct KeyStroke {
     long keyID;
     short keycode;
   struct KeyStroke {
     long keyID;
     short keycode;
+    unsigned long timestamp;
     KeyEventType type; 
     unsigned short modifiers;
   };
 
     KeyEventType type; 
     unsigned short modifiers;
   };
 
+  struct DeviceEvent {
+    long eventID;
+    short hw_code;
+    unsigned long timestamp;
+    EventType type; 
+    unsigned short modifiers;
+  };
+
   typedef sequence< long > KeySet;
   typedef sequence< KeyEventType > KeyEventTypeSeq;
 
   typedef sequence< long > KeySet;
   typedef sequence< KeyEventType > KeyEventTypeSeq;
 
@@ -194,6 +208,10 @@ module Accessibility {
         boolean keyEvent (in KeyStroke key);
   };
 
         boolean keyEvent (in KeyStroke key);
   };
 
+  interface DeviceEventListener : Bonobo::Unknown {
+        boolean notifyEvent (in DeviceEvent event);
+  };
+
   interface DeviceEventController : Bonobo::Unknown {
 
        /**
   interface DeviceEventController : Bonobo::Unknown {
 
        /**
@@ -239,6 +257,12 @@ module Accessibility {
                                        in KeyEventTypeSeq type,
                                        in boolean is_synchronous);
     
                                        in KeyEventTypeSeq type,
                                        in boolean is_synchronous);
     
+        boolean notifyListenersSync (in DeviceEventListener listener,
+                                    in DeviceEvent event);
+
+        oneway void notifyListenersAsync (in DeviceEventListener listener,
+                                         in DeviceEvent event);
+
         /**
          * generateKeyEvent:
          * @keycode: a long integer indicating the keycode of
         /**
          * generateKeyEvent:
          * @keycode: a long integer indicating the keycode of
index 04f0371..9d2e6e1 100644 (file)
@@ -60,26 +60,48 @@ static Display *display;
 static Window root_window;
 
 typedef enum {
 static Window root_window;
 
 typedef enum {
-  DEVICE_TYPE_KBD,
-  DEVICE_TYPE_MOUSE,
-  DEVICE_TYPE_LAST_DEFINED
-} DeviceTypeCategory;
+  SPI_DEVICE_TYPE_KBD,
+  SPI_DEVICE_TYPE_MOUSE,
+  SPI_DEVICE_TYPE_LAST_DEFINED
+} SpiDeviceTypeCategory;
+
+struct _DEControllerListener {
+  CORBA_Object object;
+  SpiDeviceTypeCategory type;
+};
+
+typedef struct _DEControllerListener DEControllerListener;
+
+struct _DEControllerKeyListener {
+  DEControllerListener listener;
+  Accessibility_KeySet *keys;
+  Accessibility_ControllerEventMask *mask;
+  Accessibility_KeyEventTypeSeq *typeseq;
+  gboolean is_system_global;   
+};
+
+typedef struct _DEControllerKeyListener DEControllerKeyListener;
 
 static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
 static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
 
 
 static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
 static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
 
-static void _controller_register_device_listener (SpiDeviceEventController *controller,
-                                                 const CORBA_Object l,
-                                                 DeviceTypeCategory type,
-                                                 const Accessibility_KeySet *keys,
-                                                 const Accessibility_ControllerEventMask *mask,
-                                                 CORBA_Environment *ev);
+static void controller_register_device_listener (SpiDeviceEventController *controller,
+                                                DEControllerListener *l,
+                                                CORBA_Environment *ev);
 
 /*
  * Private methods
  */
 
 static gint
 
 /*
  * Private methods
  */
 
 static gint
+_compare_listeners (gconstpointer p1, gconstpointer p2)
+{
+  DEControllerListener *l1 = (DEControllerListener *) p1;      
+  DEControllerListener *l2 = (DEControllerListener *) p2;      
+  return _compare_corba_objects (l1->object, l2->object);
+}
+
+static gint
 _compare_corba_objects (gconstpointer p1, gconstpointer p2)
 {
   CORBA_Environment ev;
 _compare_corba_objects (gconstpointer p1, gconstpointer p2)
 {
   CORBA_Environment ev;
@@ -106,44 +128,60 @@ _eventmask_compare_value (gconstpointer p1, gconstpointer p2)
     return (gint) d;
 }
 
     return (gint) d;
 }
 
+static DEControllerKeyListener *
+dec_key_listener_new (CORBA_Object l,
+                     const Accessibility_KeySet *keys,
+                     const Accessibility_ControllerEventMask *mask,
+                     const Accessibility_KeyEventTypeSeq *typeseq,
+                     const CORBA_boolean is_system_global,
+                     CORBA_Environment *ev)
+{
+  DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
+  key_listener->listener.object = CORBA_Object_duplicate (l, ev);
+  key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
+  key_listener->keys = keys;
+  key_listener->mask = mask;
+  key_listener->is_system_global = is_system_global;
+
+  return key_listener; 
+}
+
 static void
 static void
-_controller_register_device_listener (SpiDeviceEventController *controller,
-                                     const CORBA_Object l,
-                                     DeviceTypeCategory type,
-                                     const Accessibility_KeySet *keys,
-                                     const Accessibility_ControllerEventMask *mask,
-                                     CORBA_Environment *ev)
+controller_register_device_listener (SpiDeviceEventController *controller,
+                                    DEControllerListener *listener,
+                                    CORBA_Environment *ev)
 {
   Accessibility_ControllerEventMask *mask_ptr = NULL;
 {
   Accessibility_ControllerEventMask *mask_ptr = NULL;
+  DEControllerKeyListener *key_listener;
   
   
-  switch (type) {
-  case DEVICE_TYPE_KBD:
-      controller->key_listeners = g_list_append (controller->key_listeners,
-                                                CORBA_Object_duplicate (l, ev));
+  switch (listener->type) {
+  case SPI_DEVICE_TYPE_KBD:
+      key_listener = (DEControllerKeyListener *) listener;       
+      controller->key_listeners = g_list_append (controller->key_listeners, key_listener);
       
       mask_ptr = (Accessibility_ControllerEventMask *)
       
       mask_ptr = (Accessibility_ControllerEventMask *)
-             g_list_find_custom (controller->keymask_list, (gpointer) mask,
+             g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
                                  _eventmask_compare_value);
       if (mask_ptr)
              ++(mask_ptr->refcount);
       else
       {
                                  _eventmask_compare_value);
       if (mask_ptr)
              ++(mask_ptr->refcount);
       else
       {
-             if (mask->refcount != (CORBA_unsigned_short) 1)
+             if (key_listener->mask->refcount != (CORBA_unsigned_short) 1)
                      fprintf (stderr, "mask initial refcount is not 1!\n");
                      fprintf (stderr, "mask initial refcount is not 1!\n");
-             if (mask->value > (CORBA_unsigned_long) 2048)
+             if (key_listener->mask->value > (CORBA_unsigned_long) 2048)
                      fprintf (stderr, "mask value looks invalid (%lu)\n",
                      fprintf (stderr, "mask value looks invalid (%lu)\n",
-                              (unsigned long) mask->value);
+                              (unsigned long) key_listener->mask->value);
              else
                      fprintf (stderr, "appending mask with val=%lu\n",
              else
                      fprintf (stderr, "appending mask with val=%lu\n",
-                              (unsigned long) mask->value);
+                              (unsigned long) key_listener->mask->value);
              mask_ptr = Accessibility_ControllerEventMask__alloc();
              mask_ptr = Accessibility_ControllerEventMask__alloc();
-             mask_ptr->value = mask->value;
+             mask_ptr->value = key_listener->mask->value;
              mask_ptr->refcount = (CORBA_unsigned_short) 1;
              controller->keymask_list = g_list_append (controller->keymask_list,
                                                        (gpointer) mask_ptr);
       }
       break;
              mask_ptr->refcount = (CORBA_unsigned_short) 1;
              controller->keymask_list = g_list_append (controller->keymask_list,
                                                        (gpointer) mask_ptr);
       }
       break;
-  case DEVICE_TYPE_MOUSE:
+  case SPI_DEVICE_TYPE_MOUSE:
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
@@ -153,21 +191,22 @@ _controller_register_device_listener (SpiDeviceEventController *controller,
 }
 
 static void
 }
 
 static void
-_controller_deregister_device_listener (SpiDeviceEventController *controller,
-                                       const CORBA_Object l,
-                                       const Accessibility_ControllerEventMask *mask,
-                                       DeviceTypeCategory type,
-                                       CORBA_Environment *ev)
+controller_deregister_device_listener (SpiDeviceEventController *controller,
+                                      DEControllerListener *listener,
+                                      CORBA_Environment *ev)
 {
   Accessibility_ControllerEventMask *mask_ptr;
 {
   Accessibility_ControllerEventMask *mask_ptr;
+  DEControllerKeyListener *key_listener;
   GList *list_ptr;
   GList *list_ptr;
-  switch (type) {
-  case DEVICE_TYPE_KBD:
-      list_ptr = g_list_find_custom (controller->key_listeners, l, _compare_corba_objects);
+  switch (listener->type) {
+  case SPI_DEVICE_TYPE_KBD:
+      key_listener = (DEControllerKeyListener *) listener;
+      list_ptr = g_list_find_custom (controller->key_listeners, listener, _compare_listeners);
+      /* TODO: need a different custom compare func */
       if (list_ptr)
          controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
       list_ptr = (GList *)
       if (list_ptr)
          controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
       list_ptr = (GList *)
-                 g_list_find_custom (controller->keymask_list, (gpointer) mask,
+                 g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
                                     _eventmask_compare_value);
       if (list_ptr)
         {
                                     _eventmask_compare_value);
       if (list_ptr)
         {
@@ -182,7 +221,7 @@ _controller_deregister_device_listener (SpiDeviceEventController *controller,
            }
        }
       break;
            }
        }
       break;
-  case DEVICE_TYPE_MOUSE:
+  case SPI_DEVICE_TYPE_MOUSE:
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
@@ -214,6 +253,26 @@ _controller_register_with_devices (SpiDeviceEventController *controller)
   return retval;
 }
 
   return retval;
 }
 
+
+static gboolean
+notify_keylisteners (GList *key_listeners, Accessibility_KeyStroke *key_event, CORBA_Environment *ev)
+{
+  int i, n_listeners = g_list_length (key_listeners);
+  gboolean is_consumed = FALSE;
+  for (i=0; i<n_listeners && !is_consumed; ++i)
+    {
+      Accessibility_KeystrokeListener ls;
+      ls = (Accessibility_KeystrokeListener)
+           g_list_nth_data (key_listeners, i);
+      if (!CORBA_Object_is_nil(ls, ev))
+        {
+           is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, key_event, ev);
+        }              
+    }
+  return is_consumed;
+}
+
+
 static gboolean
 _check_key_event (SpiDeviceEventController *controller)
 {
 static gboolean
 _check_key_event (SpiDeviceEventController *controller)
 {
@@ -225,7 +284,6 @@ _check_key_event (SpiDeviceEventController *controller)
        gboolean is_consumed = FALSE;
        char key_name[16];
        int i;
        gboolean is_consumed = FALSE;
        char key_name[16];
        int i;
-       int n_listeners = g_list_length (controller->key_listeners);
        Accessibility_KeyStroke key_event;
        static CORBA_Environment ev;
 
        Accessibility_KeyStroke key_event;
        static CORBA_Environment ev;
 
@@ -268,16 +326,8 @@ _check_key_event (SpiDeviceEventController *controller)
 #endif
            }
            /* relay to listeners, and decide whether to consume it or not */
 #endif
            }
            /* relay to listeners, and decide whether to consume it or not */
-           for (i=0; i<n_listeners && !is_consumed; ++i)
-           {
-                   Accessibility_KeystrokeListener ls;
-                   ls = (Accessibility_KeystrokeListener)
-                           g_list_nth_data (controller->key_listeners, i);
-                   if (!CORBA_Object_is_nil(ls, &ev))
-                   {
-                           is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, &key_event, &ev);
-                   }           
-           }
+           is_consumed = notify_keylisteners (controller->key_listeners, &key_event, &ev);
+
            if (is_consumed)
            {
              XAllowEvents (display, SyncKeyboard, CurrentTime);
            if (is_consumed)
            {
              XAllowEvents (display, SyncKeyboard, CurrentTime);
@@ -363,15 +413,13 @@ impl_register_keystroke_listener (PortableServer_Servant     servant,
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
+       DEControllerKeyListener *dec_listener;
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
-        /* TODO: change this to an enum, indicating if event is caught at OS level */
-       if (is_system_global)
-       _controller_register_device_listener(controller, l, DEVICE_TYPE_KBD, keys, mask, ev);
-       else
-       ; /* register with toolkit instead */   
+       dec_listener = dec_key_listener_new (l, keys, mask, type, is_system_global, ev);
+       controller_register_device_listener (controller, (DEControllerListener *) dec_listener, ev);
 }
 
 /*
 }
 
 /*
@@ -384,16 +432,24 @@ impl_deregister_keystroke_listener (PortableServer_Servant     servant,
                                    const Accessibility_KeySet *keys,
                                    const Accessibility_ControllerEventMask *mask,
                                    const Accessibility_KeyEventTypeSeq *type,
                                    const Accessibility_KeySet *keys,
                                    const Accessibility_ControllerEventMask *mask,
                                    const Accessibility_KeyEventTypeSeq *type,
-                                   const CORBA_boolean is_synchronous,
+                                   const CORBA_boolean is_system_global,
                                    CORBA_Environment         *ev)
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
                                    CORBA_Environment         *ev)
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
+       DEControllerKeyListener *key_listener = dec_key_listener_new (l,
+                                                                     keys,
+                                                                     mask,
+                                                                     type,
+                                                                     is_system_global,
+                                                                     ev);
 #ifdef SPI_DEBUG
        fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
-       _controller_deregister_device_listener(controller, l, mask, DEVICE_TYPE_KBD, ev);
+       controller_deregister_device_listener(controller,
+                                             (DEControllerListener *) key_listener,
+                                             ev);
 }
 
 /*
 }
 
 /*
@@ -411,7 +467,7 @@ impl_register_mouse_listener (PortableServer_Servant     servant,
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering mouse listener %p\n", l);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering mouse listener %p\n", l);
 #endif
-       _controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
+       controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
 }
 */
 
 }
 */
 
index a607020..05fc512 100644 (file)
@@ -64,6 +64,8 @@ typedef enum {
   ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
+  ETYPE_KEYBOARD,
+  
   ETYPE_LAST_DEFINED
 } EventTypeCategory;
 
   ETYPE_LAST_DEFINED
 } EventTypeCategory;
 
@@ -518,6 +520,7 @@ impl_registry_notify_event (PortableServer_Servant servant,
     case (ETYPE_TOOLKIT) :
       _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
     case (ETYPE_TOOLKIT) :
       _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
+    case (ETYPE_KEYBOARD) :
     default:
       break;
     }
     default:
       break;
     }
index 04f0371..9d2e6e1 100644 (file)
@@ -60,26 +60,48 @@ static Display *display;
 static Window root_window;
 
 typedef enum {
 static Window root_window;
 
 typedef enum {
-  DEVICE_TYPE_KBD,
-  DEVICE_TYPE_MOUSE,
-  DEVICE_TYPE_LAST_DEFINED
-} DeviceTypeCategory;
+  SPI_DEVICE_TYPE_KBD,
+  SPI_DEVICE_TYPE_MOUSE,
+  SPI_DEVICE_TYPE_LAST_DEFINED
+} SpiDeviceTypeCategory;
+
+struct _DEControllerListener {
+  CORBA_Object object;
+  SpiDeviceTypeCategory type;
+};
+
+typedef struct _DEControllerListener DEControllerListener;
+
+struct _DEControllerKeyListener {
+  DEControllerListener listener;
+  Accessibility_KeySet *keys;
+  Accessibility_ControllerEventMask *mask;
+  Accessibility_KeyEventTypeSeq *typeseq;
+  gboolean is_system_global;   
+};
+
+typedef struct _DEControllerKeyListener DEControllerKeyListener;
 
 static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
 static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
 
 
 static gboolean _controller_register_with_devices (SpiDeviceEventController *controller);
 static gboolean _controller_grab_keyboard (SpiDeviceEventController *controller);
 
-static void _controller_register_device_listener (SpiDeviceEventController *controller,
-                                                 const CORBA_Object l,
-                                                 DeviceTypeCategory type,
-                                                 const Accessibility_KeySet *keys,
-                                                 const Accessibility_ControllerEventMask *mask,
-                                                 CORBA_Environment *ev);
+static void controller_register_device_listener (SpiDeviceEventController *controller,
+                                                DEControllerListener *l,
+                                                CORBA_Environment *ev);
 
 /*
  * Private methods
  */
 
 static gint
 
 /*
  * Private methods
  */
 
 static gint
+_compare_listeners (gconstpointer p1, gconstpointer p2)
+{
+  DEControllerListener *l1 = (DEControllerListener *) p1;      
+  DEControllerListener *l2 = (DEControllerListener *) p2;      
+  return _compare_corba_objects (l1->object, l2->object);
+}
+
+static gint
 _compare_corba_objects (gconstpointer p1, gconstpointer p2)
 {
   CORBA_Environment ev;
 _compare_corba_objects (gconstpointer p1, gconstpointer p2)
 {
   CORBA_Environment ev;
@@ -106,44 +128,60 @@ _eventmask_compare_value (gconstpointer p1, gconstpointer p2)
     return (gint) d;
 }
 
     return (gint) d;
 }
 
+static DEControllerKeyListener *
+dec_key_listener_new (CORBA_Object l,
+                     const Accessibility_KeySet *keys,
+                     const Accessibility_ControllerEventMask *mask,
+                     const Accessibility_KeyEventTypeSeq *typeseq,
+                     const CORBA_boolean is_system_global,
+                     CORBA_Environment *ev)
+{
+  DEControllerKeyListener *key_listener = g_new0 (DEControllerKeyListener, 1);
+  key_listener->listener.object = CORBA_Object_duplicate (l, ev);
+  key_listener->listener.type = SPI_DEVICE_TYPE_KBD;
+  key_listener->keys = keys;
+  key_listener->mask = mask;
+  key_listener->is_system_global = is_system_global;
+
+  return key_listener; 
+}
+
 static void
 static void
-_controller_register_device_listener (SpiDeviceEventController *controller,
-                                     const CORBA_Object l,
-                                     DeviceTypeCategory type,
-                                     const Accessibility_KeySet *keys,
-                                     const Accessibility_ControllerEventMask *mask,
-                                     CORBA_Environment *ev)
+controller_register_device_listener (SpiDeviceEventController *controller,
+                                    DEControllerListener *listener,
+                                    CORBA_Environment *ev)
 {
   Accessibility_ControllerEventMask *mask_ptr = NULL;
 {
   Accessibility_ControllerEventMask *mask_ptr = NULL;
+  DEControllerKeyListener *key_listener;
   
   
-  switch (type) {
-  case DEVICE_TYPE_KBD:
-      controller->key_listeners = g_list_append (controller->key_listeners,
-                                                CORBA_Object_duplicate (l, ev));
+  switch (listener->type) {
+  case SPI_DEVICE_TYPE_KBD:
+      key_listener = (DEControllerKeyListener *) listener;       
+      controller->key_listeners = g_list_append (controller->key_listeners, key_listener);
       
       mask_ptr = (Accessibility_ControllerEventMask *)
       
       mask_ptr = (Accessibility_ControllerEventMask *)
-             g_list_find_custom (controller->keymask_list, (gpointer) mask,
+             g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
                                  _eventmask_compare_value);
       if (mask_ptr)
              ++(mask_ptr->refcount);
       else
       {
                                  _eventmask_compare_value);
       if (mask_ptr)
              ++(mask_ptr->refcount);
       else
       {
-             if (mask->refcount != (CORBA_unsigned_short) 1)
+             if (key_listener->mask->refcount != (CORBA_unsigned_short) 1)
                      fprintf (stderr, "mask initial refcount is not 1!\n");
                      fprintf (stderr, "mask initial refcount is not 1!\n");
-             if (mask->value > (CORBA_unsigned_long) 2048)
+             if (key_listener->mask->value > (CORBA_unsigned_long) 2048)
                      fprintf (stderr, "mask value looks invalid (%lu)\n",
                      fprintf (stderr, "mask value looks invalid (%lu)\n",
-                              (unsigned long) mask->value);
+                              (unsigned long) key_listener->mask->value);
              else
                      fprintf (stderr, "appending mask with val=%lu\n",
              else
                      fprintf (stderr, "appending mask with val=%lu\n",
-                              (unsigned long) mask->value);
+                              (unsigned long) key_listener->mask->value);
              mask_ptr = Accessibility_ControllerEventMask__alloc();
              mask_ptr = Accessibility_ControllerEventMask__alloc();
-             mask_ptr->value = mask->value;
+             mask_ptr->value = key_listener->mask->value;
              mask_ptr->refcount = (CORBA_unsigned_short) 1;
              controller->keymask_list = g_list_append (controller->keymask_list,
                                                        (gpointer) mask_ptr);
       }
       break;
              mask_ptr->refcount = (CORBA_unsigned_short) 1;
              controller->keymask_list = g_list_append (controller->keymask_list,
                                                        (gpointer) mask_ptr);
       }
       break;
-  case DEVICE_TYPE_MOUSE:
+  case SPI_DEVICE_TYPE_MOUSE:
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
@@ -153,21 +191,22 @@ _controller_register_device_listener (SpiDeviceEventController *controller,
 }
 
 static void
 }
 
 static void
-_controller_deregister_device_listener (SpiDeviceEventController *controller,
-                                       const CORBA_Object l,
-                                       const Accessibility_ControllerEventMask *mask,
-                                       DeviceTypeCategory type,
-                                       CORBA_Environment *ev)
+controller_deregister_device_listener (SpiDeviceEventController *controller,
+                                      DEControllerListener *listener,
+                                      CORBA_Environment *ev)
 {
   Accessibility_ControllerEventMask *mask_ptr;
 {
   Accessibility_ControllerEventMask *mask_ptr;
+  DEControllerKeyListener *key_listener;
   GList *list_ptr;
   GList *list_ptr;
-  switch (type) {
-  case DEVICE_TYPE_KBD:
-      list_ptr = g_list_find_custom (controller->key_listeners, l, _compare_corba_objects);
+  switch (listener->type) {
+  case SPI_DEVICE_TYPE_KBD:
+      key_listener = (DEControllerKeyListener *) listener;
+      list_ptr = g_list_find_custom (controller->key_listeners, listener, _compare_listeners);
+      /* TODO: need a different custom compare func */
       if (list_ptr)
          controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
       list_ptr = (GList *)
       if (list_ptr)
          controller->key_listeners = g_list_remove (controller->key_listeners, list_ptr);
       list_ptr = (GList *)
-                 g_list_find_custom (controller->keymask_list, (gpointer) mask,
+                 g_list_find_custom (controller->keymask_list, (gpointer) key_listener->mask,
                                     _eventmask_compare_value);
       if (list_ptr)
         {
                                     _eventmask_compare_value);
       if (list_ptr)
         {
@@ -182,7 +221,7 @@ _controller_deregister_device_listener (SpiDeviceEventController *controller,
            }
        }
       break;
            }
        }
       break;
-  case DEVICE_TYPE_MOUSE:
+  case SPI_DEVICE_TYPE_MOUSE:
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
 /*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
                                                    CORBA_Object_duplicate (l, ev));*/
 
@@ -214,6 +253,26 @@ _controller_register_with_devices (SpiDeviceEventController *controller)
   return retval;
 }
 
   return retval;
 }
 
+
+static gboolean
+notify_keylisteners (GList *key_listeners, Accessibility_KeyStroke *key_event, CORBA_Environment *ev)
+{
+  int i, n_listeners = g_list_length (key_listeners);
+  gboolean is_consumed = FALSE;
+  for (i=0; i<n_listeners && !is_consumed; ++i)
+    {
+      Accessibility_KeystrokeListener ls;
+      ls = (Accessibility_KeystrokeListener)
+           g_list_nth_data (key_listeners, i);
+      if (!CORBA_Object_is_nil(ls, ev))
+        {
+           is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, key_event, ev);
+        }              
+    }
+  return is_consumed;
+}
+
+
 static gboolean
 _check_key_event (SpiDeviceEventController *controller)
 {
 static gboolean
 _check_key_event (SpiDeviceEventController *controller)
 {
@@ -225,7 +284,6 @@ _check_key_event (SpiDeviceEventController *controller)
        gboolean is_consumed = FALSE;
        char key_name[16];
        int i;
        gboolean is_consumed = FALSE;
        char key_name[16];
        int i;
-       int n_listeners = g_list_length (controller->key_listeners);
        Accessibility_KeyStroke key_event;
        static CORBA_Environment ev;
 
        Accessibility_KeyStroke key_event;
        static CORBA_Environment ev;
 
@@ -268,16 +326,8 @@ _check_key_event (SpiDeviceEventController *controller)
 #endif
            }
            /* relay to listeners, and decide whether to consume it or not */
 #endif
            }
            /* relay to listeners, and decide whether to consume it or not */
-           for (i=0; i<n_listeners && !is_consumed; ++i)
-           {
-                   Accessibility_KeystrokeListener ls;
-                   ls = (Accessibility_KeystrokeListener)
-                           g_list_nth_data (controller->key_listeners, i);
-                   if (!CORBA_Object_is_nil(ls, &ev))
-                   {
-                           is_consumed = Accessibility_KeystrokeListener_keyEvent (ls, &key_event, &ev);
-                   }           
-           }
+           is_consumed = notify_keylisteners (controller->key_listeners, &key_event, &ev);
+
            if (is_consumed)
            {
              XAllowEvents (display, SyncKeyboard, CurrentTime);
            if (is_consumed)
            {
              XAllowEvents (display, SyncKeyboard, CurrentTime);
@@ -363,15 +413,13 @@ impl_register_keystroke_listener (PortableServer_Servant     servant,
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
+       DEControllerKeyListener *dec_listener;
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
-        /* TODO: change this to an enum, indicating if event is caught at OS level */
-       if (is_system_global)
-       _controller_register_device_listener(controller, l, DEVICE_TYPE_KBD, keys, mask, ev);
-       else
-       ; /* register with toolkit instead */   
+       dec_listener = dec_key_listener_new (l, keys, mask, type, is_system_global, ev);
+       controller_register_device_listener (controller, (DEControllerListener *) dec_listener, ev);
 }
 
 /*
 }
 
 /*
@@ -384,16 +432,24 @@ impl_deregister_keystroke_listener (PortableServer_Servant     servant,
                                    const Accessibility_KeySet *keys,
                                    const Accessibility_ControllerEventMask *mask,
                                    const Accessibility_KeyEventTypeSeq *type,
                                    const Accessibility_KeySet *keys,
                                    const Accessibility_ControllerEventMask *mask,
                                    const Accessibility_KeyEventTypeSeq *type,
-                                   const CORBA_boolean is_synchronous,
+                                   const CORBA_boolean is_system_global,
                                    CORBA_Environment         *ev)
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
                                    CORBA_Environment         *ev)
 {
        SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
                bonobo_object_from_servant (servant));
+       DEControllerKeyListener *key_listener = dec_key_listener_new (l,
+                                                                     keys,
+                                                                     mask,
+                                                                     type,
+                                                                     is_system_global,
+                                                                     ev);
 #ifdef SPI_DEBUG
        fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
                 (void *) l, (unsigned long) mask->value);
 #endif
-       _controller_deregister_device_listener(controller, l, mask, DEVICE_TYPE_KBD, ev);
+       controller_deregister_device_listener(controller,
+                                             (DEControllerListener *) key_listener,
+                                             ev);
 }
 
 /*
 }
 
 /*
@@ -411,7 +467,7 @@ impl_register_mouse_listener (PortableServer_Servant     servant,
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering mouse listener %p\n", l);
 #endif
 #ifdef SPI_DEBUG
        fprintf (stderr, "registering mouse listener %p\n", l);
 #endif
-       _controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
+       controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
 }
 */
 
 }
 */
 
index a607020..05fc512 100644 (file)
@@ -64,6 +64,8 @@ typedef enum {
   ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_PROPERTY,
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
+  ETYPE_KEYBOARD,
+  
   ETYPE_LAST_DEFINED
 } EventTypeCategory;
 
   ETYPE_LAST_DEFINED
 } EventTypeCategory;
 
@@ -518,6 +520,7 @@ impl_registry_notify_event (PortableServer_Servant servant,
     case (ETYPE_TOOLKIT) :
       _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
     case (ETYPE_TOOLKIT) :
       _registry_notify_listeners (registry->toolkit_listeners, e, ev); 
       break;
+    case (ETYPE_KEYBOARD) :
     default:
       break;
     }
     default:
       break;
     }