[g-a-devel]proto at-spi patch ...



Hi Bill,

	This patch removes the timeout polling, and well - does a load of work
around the place. However, for some reason strace reveals I'm not
receiving the keyboard input as I am expecting too.

	Being no X expert; I have no idea how to ask X to allow us to filter
all keyboard events on a display, and until I can get that to happen I'm
somewhat stymied - and all that just to test whether the thing works
still.

	So - can you give it a read, and let me know your thoughts / how to get
those X events.

	I'd like to commit the 'const' change to the event passing API -
clients shouldn't be fiddling with the events we send them; and that
breaks no code [ but makes some old code spew warnings ].

	I'd also like to  rename SpiDeviceEventController to SpiController in
the C implementation it, would save a lot of typing and this header /
impl. is not installed.

	I'm also concerned to some degree that we need to be able to detect
when apps that have asked the registry to take a keygrab die - otherwise
we're going to leak keygrabs - which is a pernicious evil. Do we have
the API strength to do this ?

	Using the CSPI API it's not clear when adding a keygrab what values to
pass as AccessibleKeyMaskType, or for the AccessibleKeyEventMask, the
SPI_KEYLISTENER_ALL_WINDOWS sync type is not quite clear to me either.
Can we elucidate with comments, enums or typedefs ?

	Regards,

		Michael.

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/at-spi/ChangeLog,v
retrieving revision 1.134
diff -u -p -u -r1.134 ChangeLog
--- ChangeLog	2002/01/08 09:11:43	1.134
+++ ChangeLog	2002/01/09 12:13:34
@@ -1,5 +1,69 @@
 2002-01-08  Michael Meeks  <michael ximian com>
 
+	* registryd/deviceeventcontroller.c
+	(spi_controller_register_with_devices): use gdk calls to
+	setup a filter.
+	(global_filter_fn): implement the filter.
+	(spi_device_event_controller_check_key_event): rename to
+	(spi_device_event_controller_forward_key_event): this & upd.
+	(spi_get_display): replace with GDK_DISPLAY.
+
+	* test/test-simple.c (key_listener_cb): impl.
+	(test_keylisteners): impl.
+
+	* cspi/spi-listener.h: make listener signatures const
+	on the provided (const) events.
+
+	* test/keysynth-demo.c: upd. to const events.
+
+	* test/simple-at.c: ditto.
+
+	* registryd/deviceeventcontroller.c
+	(spi_controller_deregister_device_listener): unroll into
+	(impl_deregister_keystroke_listener): here to simplify.
+	(spi_controller_register_global_keygrabs): split cut and
+	paste (!) out into (_register_keygrab): here, shorter & sweeter.
+	(spi_controller_deregister_device_listener): remove.
+	(impl_register_mouse_listener): remove, no mouse listener
+	support in at-spi-1.0
+
+	* registryd/registry.c
+	(_device_event_controller_hook): kill.
+	(spi_registry_init): upd.
+
+	* registryd/deviceeventcontroller.c
+	(spi_device_event_controller_class_init): upd.
+	(spi_check_key_event): merge into.
+	(spi_device_event_controller_check_key_event):
+	here and kill strange static ev init, don't leak
+	the x_event - nor dynamicaly allocate it.
+
+	* registryd/registry-main.c (main): re-direct
+	timeout to remove strange vtable mess.
+
+	* registryd/deviceeventcontroller.c
+	(remove_listener_cb): impl.
+	(spi_controller_deregister_device_listener):
+	fix re-enterancy hazard.
+
+2002-01-07  Michael Meeks  <michael ximian com>
+
+	* registryd/deviceeventcontroller.c
+	(spi_device_event_controller_new): upd.
+	(impl_notify_listeners_sync): upd. debug.
+	(spi_notify_keylisteners): fix re-enterancy hazards,
+	prettify, remove O(n*n) iteration.
+	(spi_controller_grab_keyboard): fix iteration.
+	(spi_check_key_event): re-format to suit coding style.
+	Clean all the warnings - we're warning free.
+
+	* registryd/deviceeventcontroller.h:
+	* registryd/registry.h: make mutualy referential with
+	typesafe forward references instead of (!) void pointer
+	hacks.
+
+2002-01-08  Michael Meeks  <michael ximian com>
+
 	* registryd/registry.c (parse_event_type): remove strndup.
 
 	* libspi/Makefile.am (libspi_la_SOURCES): remove
Index: cspi/spi-listener.h
===================================================================
RCS file: /cvs/gnome/at-spi/cspi/spi-listener.h,v
retrieving revision 1.15
diff -u -p -u -r1.15 spi-listener.h
--- cspi/spi-listener.h	2001/12/18 11:24:56	1.15
+++ cspi/spi-listener.h	2002/01/09 12:13:34
@@ -42,10 +42,10 @@ typedef struct {
  *
  * SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystrokeEvent *Event);
  */
-typedef void       (*AccessibleEventListenerCB)     (AccessibleEvent     *event,
-						     void                *user_data);
-typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (AccessibleKeystroke *stroke,
-						     void                *user_data);
+typedef void       (*AccessibleEventListenerCB)     (const AccessibleEvent *event,
+						     void                  *user_data);
+typedef SPIBoolean (*AccessibleKeystrokeListenerCB) (const AccessibleKeystroke *stroke,
+						     void                      *user_data);
 
 #ifdef  __cplusplus
 }
Index: cspi/spi_registry.c
===================================================================
RCS file: /cvs/gnome/at-spi/cspi/spi_registry.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 spi_registry.c
--- cspi/spi_registry.c	2002/01/08 09:11:44	1.28
+++ cspi/spi_registry.c	2002/01/09 12:13:35
@@ -310,10 +310,10 @@ SPI_freeDesktopList (Accessible **deskto
  * Returns: #TRUE if successful, otherwise #FALSE.
  **/
 SPIBoolean
-SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener,
-					 AccessibleKeySet *keys,
-					 AccessibleKeyMaskType modmask,
-					 AccessibleKeyEventMask eventmask,
+SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener  *listener,
+					 AccessibleKeySet             *keys,
+					 AccessibleKeyMaskType         modmask,
+					 AccessibleKeyEventMask        eventmask,
 					 AccessibleKeyListenerSyncType sync_type)
 {
   gint                                i, mask;
Index: idl/Accessibility_Registry.idl
===================================================================
RCS file: /cvs/gnome/at-spi/idl/Accessibility_Registry.idl,v
retrieving revision 1.16
diff -u -p -u -r1.16 Accessibility_Registry.idl
--- idl/Accessibility_Registry.idl	2002/01/01 22:35:29	1.16
+++ idl/Accessibility_Registry.idl	2002/01/09 12:13:35
@@ -66,7 +66,7 @@ module Accessibility {
          *
 	 **/
         void registerGlobalEventListener (in EventListener listener,
-                                           in string eventName);
+					  in string eventName);
 
   	/**
          * deregisterGlobalEventListener:
Index: registryd/deviceeventcontroller.c
===================================================================
RCS file: /cvs/gnome/at-spi/registryd/deviceeventcontroller.c,v
retrieving revision 1.27
diff -u -p -u -r1.27 deviceeventcontroller.c
--- registryd/deviceeventcontroller.c	2002/01/08 09:11:46	1.27
+++ registryd/deviceeventcontroller.c	2002/01/09 12:13:35
@@ -24,19 +24,23 @@
 
 #include <config.h>
 
-#undef SPI_DEBUG
+#define SPI_DEBUG
 
-#ifdef SPI_DEBUG
-#  include <stdio.h>
-#endif
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <bonobo/bonobo-exception.h>
 
 #include <X11/Xlib.h>
 #include <X11/extensions/XTest.h>
 #define XK_MISCELLANY
 #include <X11/keysymdef.h>
+#include <gdk/gdk.h>
 #include <gdk/gdkx.h> /* TODO: hide dependency (wrap in single porting file) */
+#include <gdk/gdkkeysyms.h>
 #include <gdk/gdkwindow.h>
 
+#include "../libspi/spi-private.h"
 #include "deviceeventcontroller.h"
 
 /* Our parent Gtk object type */
@@ -45,98 +49,51 @@
 /* A pointer to our parent object class */
 static GObjectClass *spi_device_event_controller_parent_class;
 
-static gboolean kbd_registered = FALSE;
-
 static Window root_window;
 
 typedef enum {
   SPI_DEVICE_TYPE_KBD,
-  SPI_DEVICE_TYPE_MOUSE,
   SPI_DEVICE_TYPE_LAST_DEFINED
 } SpiDeviceTypeCategory;
 
-struct _DEControllerGrabMask {
+typedef struct {
   Accessibility_ControllerEventMask modmask;
   CORBA_unsigned_long               keyval;
   unsigned int                      refcount;
-};
-
-typedef struct _DEControllerGrabMask DEControllerGrabMask;
+} DEControllerGrabMask;
 
-struct _DEControllerListener {
+typedef struct {
   CORBA_Object          object;
   SpiDeviceTypeCategory type;
-};
-
-typedef struct _DEControllerListener DEControllerListener;
+} DEControllerListener;
 
-struct _DEControllerKeyListener {
+typedef struct {
   DEControllerListener listener;
-  Accessibility_KeySet *keys;
-  Accessibility_ControllerEventMask mask;
-  Accessibility_KeyEventTypeSeq *typeseq;
-  Accessibility_EventListenerMode *mode;	
-};
-
-typedef struct _DEControllerKeyListener DEControllerKeyListener;
-
-static gboolean spi_controller_register_with_devices (SpiDeviceEventController *controller);
-static gboolean spi_controller_grab_keyboard (SpiDeviceEventController *controller);
-
-static void spi_controller_register_device_listener (SpiDeviceEventController *controller,
-						     DEControllerListener *l,
-						     CORBA_Environment *ev);
 
-/*
- * Private methods
- */
+  Accessibility_KeySet             *keys;
+  Accessibility_ControllerEventMask mask;
+  Accessibility_KeyEventTypeSeq    *typeseq;
+  Accessibility_EventListenerMode  *mode;	
+} DEControllerKeyListener;
+
+static void     spi_controller_register_with_devices          (SpiDeviceEventController *controller);
+static gboolean spi_controller_grab_keyboard                  (SpiDeviceEventController *controller);
+static void     spi_controller_register_device_listener       (SpiDeviceEventController *controller,
+							       DEControllerListener     *l,
+							       CORBA_Environment        *ev);
+static void     spi_device_event_controller_forward_key_event (SpiDeviceEventController *controller,
+							       const XEvent             *event);
 
-static Display *
-spi_get_display (void )
-{
- static Display *display = NULL;
- /* We must open a new connection to the server to avoid clashing with the GDK event loop */
- /*
-  * TODO: fixme, this makes the foolish assumption that registryd uses
-  * the same display as the apps, and the the DISPLAY environment variable is set.
-  */
- 
- if (!display)
-   {
-     display = XOpenDisplay (g_getenv ("DISPLAY"));
-   }
- return display;
-}
+/* Private methods */
 
 static DEControllerGrabMask *
 spi_grabmask_clone (DEControllerGrabMask *grabmask)
-{
-  DEControllerGrabMask *clone = g_new0 (DEControllerGrabMask, 1);
-  memcpy (clone, grabmask, sizeof (DEControllerGrabMask));
-  return clone;
-}
-
-static gint
-spi_compare_corba_objects (gconstpointer p1, gconstpointer p2)
 {
-  CORBA_Environment ev;
-  gint retval;
-  retval = !CORBA_Object_is_equivalent ((CORBA_Object) p1, (CORBA_Object) p2, &ev);
+  DEControllerGrabMask *clone = g_new (DEControllerGrabMask, 1);
 
-#ifdef SPI_DEBUG
-  fprintf (stderr, "comparing %p to %p; result %d\n",
-	   p1, p2,
-	   retval);
-#endif
-  return retval;  
-}
+  memcpy (clone, grabmask, sizeof (DEControllerGrabMask));
 
-static gint
-spi_compare_listeners (gconstpointer p1, gconstpointer p2)
-{
-  DEControllerListener *l1 = (DEControllerListener *) p1;	
-  DEControllerListener *l2 = (DEControllerListener *) p2;	
-  return spi_compare_corba_objects (l1->object, l2->object);
+  return clone;
 }
 
 static gint
@@ -181,11 +138,13 @@ spi_dec_key_listener_new (CORBA_Object l
            (int) mode->global,
 	   (void *) key_listener->keys);
 #endif
+
   return key_listener;	
 }
 
 static void
-spi_dec_key_listener_free (DEControllerKeyListener *key_listener, CORBA_Environment *ev)
+spi_dec_key_listener_free (DEControllerKeyListener *key_listener,
+			   CORBA_Environment       *ev)
 {
   bonobo_object_release_unref (key_listener->listener.object, ev);
   CORBA_free (key_listener->typeseq);
@@ -195,75 +154,70 @@ spi_dec_key_listener_free (DEControllerK
 
 static void
 spi_controller_deregister_global_keygrabs (SpiDeviceEventController *controller,
-					   DEControllerKeyListener *key_listener)
+					   DEControllerKeyListener  *key_listener)
 {
-  GList *list_ptr;
-  DEControllerGrabMask *mask_ptr;
   /* TODO: implement this! Also remember to release any keygrabs still held */
-  ;
+}
+
+static void
+_register_keygrab (SpiDeviceEventController *controller,
+		   DEControllerGrabMask     *grabmask)
+{
+  GList *l;
+
+  l = g_list_find_custom (controller->keygrabs_list, grabmask,
+			  spi_grabmask_compare_values);
+  if (l)
+    {
+      DEControllerGrabMask *cur_mask = l->data;
+
+      cur_mask->refcount++;
+    }
+  else
+    {
+      controller->keygrabs_list =
+        g_list_prepend (controller->keygrabs_list,
+			spi_grabmask_clone (grabmask));
+    }
 }
 
 static void
 spi_controller_register_global_keygrabs (SpiDeviceEventController *controller,
-					 DEControllerKeyListener *key_listener)
+					 DEControllerKeyListener  *key_listener)
 {
-  DEControllerGrabMask grabmask, *grabmask_ptr;
-  GList *list_ptr;
-  gint i;
+  DEControllerGrabMask grabmask;
+
   /* TODO: deregistration version of this function */
   
   grabmask.modmask = key_listener->mask;
   if (key_listener->keys->_length == 0) /* special case means AnyKey/AllKeys */
     {
       grabmask.keyval = AnyKey;
-      list_ptr = g_list_find_custom (controller->keygrabs_list, &grabmask,
-				     spi_grabmask_compare_values);
-      if (list_ptr)
-        {
-          grabmask_ptr = (DEControllerGrabMask *) list_ptr->data;
-	  grabmask_ptr->refcount++;
-        }
-      else
-        {
-	  controller->keygrabs_list =
-		  g_list_prepend (controller->keygrabs_list,
-				  spi_grabmask_clone (&grabmask));
-        }
+      _register_keygrab (controller, &grabmask);
     }
   else
     {
+      int i;
+
       for (i = 0; i < key_listener->keys->_length; ++i)
         {
 	  long int keyval = key_listener->keys->_buffer[i];
 	  /* X Grabs require keycodes, not keysyms */
 	  if (keyval >= 0)
 	    {
-	      keyval = XKeysymToKeycode(spi_get_display (), (KeySym) keyval);		    
+	      keyval = XKeysymToKeycode (GDK_DISPLAY (), (KeySym) keyval);
 	    }
 	  grabmask.keyval = keyval;
-          list_ptr = g_list_find_custom (controller->keygrabs_list, &grabmask,
-					     spi_grabmask_compare_values);
-          if (list_ptr)
-            {
-	      grabmask_ptr = (DEControllerGrabMask *) list_ptr->data;
-              grabmask_ptr->refcount++;
-            }
-          else
-            {
-	      controller->keygrabs_list =
-		  g_list_prepend (controller->keygrabs_list,
-				  spi_grabmask_clone (&grabmask));
-	      fprintf (stderr, "appending mask with val=%lu\n",
-		       (unsigned long) grabmask.modmask);
-            }
-        }
+
+	  _register_keygrab (controller, &grabmask);
+	}
     }
 }
 
 static void
 spi_controller_register_device_listener (SpiDeviceEventController *controller,
-					 DEControllerListener *listener,
-					 CORBA_Environment *ev)
+					 DEControllerListener     *listener,
+					 CORBA_Environment        *ev)
 {
   DEControllerKeyListener *key_listener;
   
@@ -276,74 +230,65 @@ spi_controller_register_device_listener 
 	  spi_controller_register_global_keygrabs (controller, key_listener);	
 	}
       break;
-  case SPI_DEVICE_TYPE_MOUSE:
-/*    controller->mouse_listeners = g_list_append (controller->mouse_listeners,
-                                                   CORBA_Object_duplicate (l, ev));*/
-
-/* this interface should only be used for mouse motion events, not mouse clicks events */
+    default:
       break;
   }
 }
 
-static void
-spi_controller_deregister_device_listener (SpiDeviceEventController *controller,
-					   DEControllerListener *listener,
-					   CORBA_Environment *ev)
-{
-  Accessibility_ControllerEventMask *mask_ptr;
-  DEControllerListener *dec_listener;
-  GList *list_ptr;
-  switch (listener->type)
-    {
-      case SPI_DEVICE_TYPE_KBD:
-        spi_controller_deregister_global_keygrabs (controller,
-						   (DEControllerKeyListener *) listener);
-
-        /* now, remove this listener from the keylistener list */
-        list_ptr = g_list_find_custom (controller->key_listeners, listener, spi_compare_listeners);
-        if (list_ptr)
-          {
-	    dec_listener = (DEControllerListener *) list_ptr->data;
-#ifdef SPI_DEBUG	  
-	    g_print ("removing keylistener %p\n", dec_listener->object);
-#endif
-	    controller->key_listeners = g_list_remove_link (controller->key_listeners,
-							  list_ptr);
-	    spi_dec_key_listener_free ((DEControllerKeyListener *) dec_listener, ev);
-	  }
-        break;
-      case SPI_DEVICE_TYPE_MOUSE: /* TODO: implement */
-        break;
+static GdkFilterReturn
+global_filter_fn (GdkXEvent *gdk_xevent,
+		  GdkEvent  *event,
+		  gpointer   data)
+{
+  XEvent *xevent = gdk_xevent;
+  SpiDeviceEventController *controller;
+
+  if (xevent->type != KeyPress && xevent->type != KeyRelease)
+    {
+      g_print ("Event %d\n", xevent->type);
+      return GDK_FILTER_CONTINUE;
     }
+
+  controller = SPI_DEVICE_EVENT_CONTROLLER (data);
+
+  spi_device_event_controller_forward_key_event (controller, xevent);
+
+  /* FIXME: is this right ? */
+  return GDK_FILTER_CONTINUE;
 }
 
-static gboolean
+static void
 spi_controller_register_with_devices (SpiDeviceEventController *controller)
 {
-  gboolean retval = FALSE;
-
   /* calls to device-specific implementations and routines go here */
   /* register with: keyboard hardware code handler */
   /* register with: (translated) keystroke handler */
 
-  /* We must open a new connection to the server to avoid clashing with the GDK event loop */
-  root_window = DefaultRootWindow (spi_get_display ());		
-  XSelectInput (spi_get_display (),
-		root_window,
+/*  root_window = DefaultRootWindow (GDK_DISPLAY ());		
+    XSelectInput (GDK_DISPLAY (), root_window, KeyPressMask | KeyReleaseMask);*/
+
+  gdk_window_add_filter (NULL, global_filter_fn, controller);
+
+  gdk_window_set_events (gdk_get_default_root_window (),
+			 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+
+  XSelectInput (GDK_DISPLAY (),
+		DefaultRootWindow (GDK_DISPLAY ()),
 		KeyPressMask | KeyReleaseMask);
-  /* register with: mouse hardware device handler? */
-  /* register with: mouse event handler */
-  return retval;
 }
 
 static gboolean
-spi_key_set_contains_key (Accessibility_KeySet *key_set, const Accessibility_DeviceEvent *key_event)
+spi_key_set_contains_key (Accessibility_KeySet            *key_set,
+			  const Accessibility_DeviceEvent *key_event)
 {
   gint i;
   gint len;
 
-  /* g_assert (key_set); */
-  if (!key_set) { g_print ("null key set!"); return TRUE; }
+  if (!key_set)
+    {
+      g_print ("null key set!");
+      return TRUE;
+    }
 
   len = key_set->_length;
   
@@ -353,17 +298,21 @@ spi_key_set_contains_key (Accessibility_
       return TRUE;
     }
 
-  for (i=0; i<len; ++i)
+  for (i = 0; i < len; ++i)
     {
 #ifdef SPI_KEYEVENT_DEBUG	    
       g_print ("key_set[%d] = %d; key_event %d, code %d\n",
-	        i,
-	       (int) key_set->_buffer[i],
-	       (int) key_event->id,
-	       (int) key_event->hw_code); 
+	        i, (int) key_set->_buffer[i],
+	       (int) key_event->id, (int) key_event->hw_code); 
 #endif
-      if (key_set->_buffer[i] == (CORBA_long) key_event->id) return TRUE;
-      if (key_set->_buffer[i] == (CORBA_long) -key_event->hw_code) return TRUE;
+      if (key_set->_buffer[i] == (CORBA_long) key_event->id)
+        {
+          return TRUE;
+	}
+      if (key_set->_buffer[i] == (CORBA_long) -key_event->hw_code)
+        {
+          return TRUE;
+	}
     }
   
   return FALSE;
@@ -375,9 +324,13 @@ spi_key_eventtype_seq_contains_event (Ac
 {
   gint i;
   gint len;
+
 
-  /* g_assert (type_seq); */
-  if (!type_seq) { g_print ("null type seq!"); return TRUE; }
+  if (!type_seq)
+    {
+      g_print ("null type seq!");
+      return TRUE;
+    }
 
   len = type_seq->_length;
   
@@ -386,13 +339,16 @@ spi_key_eventtype_seq_contains_event (Ac
       return TRUE;
     }
 
-  for (i=0; i<len; ++i)
+  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; key event type = %d\n", i,
+	       (int) type_seq->_buffer[i], (int) key_event->type);
 #endif      
-      if (type_seq->_buffer[i] == (CORBA_long) key_event->type) return TRUE;	    
+      if (type_seq->_buffer[i] == (CORBA_long) key_event->type)
+        {
+          return TRUE;
+	}
     }
   
   return FALSE;
@@ -404,6 +360,7 @@ spi_key_event_matches_listener (const Ac
 				CORBA_boolean                    is_system_global)
 {
   g_print ("checking keycode %d\n", (int) key_event->hw_code);
+
   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) && 
@@ -412,39 +369,71 @@ spi_key_event_matches_listener (const Ac
       return TRUE;
     }
   else
-    return FALSE;
+    {
+      return FALSE;
+    }
 }
 
 static gboolean
-spi_notify_keylisteners (GList *key_listeners,
+spi_notify_keylisteners (GList                          **key_listeners,
 			 const Accessibility_DeviceEvent *key_event,
-			 CORBA_boolean is_system_global,
-			 CORBA_Environment *ev)
+			 CORBA_boolean                    is_system_global,
+			 CORBA_Environment               *ev)
 {
-  int i, n_listeners = g_list_length (key_listeners);
-  gboolean is_consumed = FALSE;
+  GList   *l;
+  GSList  *notify = NULL, *l2;
+  gboolean is_consumed;
 
-  for (i=0; i<n_listeners && !is_consumed; ++i)
+  if (!key_listeners)
     {
-      Accessibility_DeviceEventListener ls;
-      DEControllerKeyListener *key_listener = (DEControllerKeyListener *)
-	    g_list_nth_data (key_listeners, i);
-      ls = (Accessibility_DeviceEventListener) key_listener->listener.object;
-      if (spi_key_event_matches_listener (key_event, key_listener, is_system_global))
-        {
-          if (!CORBA_Object_is_nil(ls, ev))
-            {
-	      is_consumed = Accessibility_DeviceEventListener_notifyEvent (ls, key_event, ev);
-            }		
-        }
-      else
-        {
+      return FALSE;
+    }
+
+  for (l = *key_listeners; l; l = l->next)
+    {
+       DEControllerKeyListener *key_listener = l->data;
+
+       if (spi_key_event_matches_listener (key_event, key_listener, is_system_global))
+         {
+           Accessibility_DeviceEventListener ls = key_listener->listener.object;
+
+	   if (ls != CORBA_OBJECT_NIL)
+	     {
+               notify = g_slist_prepend (notify, CORBA_Object_duplicate (ls, ev));
+	     }
+         }
+    }
+
 #ifdef SPI_KEYEVENT_DEBUG
-	      g_print ("no match for listener %d\n", i);
+  if (!notify)
+    {
+      g_print ("no match for listener %d\n", i);
+    }
 #endif
-	      ;
-	}
+
+  is_consumed = FALSE;
+  for (l2 = notify; l2 && !is_consumed; l2 = l2->next)
+    {
+      Accessibility_DeviceEventListener ls = l2->data;
+
+      is_consumed = Accessibility_DeviceEventListener_notifyEvent (ls, key_event, ev);
+
+      if (BONOBO_EX (ev))
+        {
+          is_consumed = FALSE;
+	  CORBA_exception_free (ev);
+        }
+
+      CORBA_Object_release (ls, ev);
+    }
+
+  for (; l2; l2 = l2->next)
+    {
+      CORBA_Object_release (l2->data, ev);
     }
+
+  g_slist_free (notify);
+  
   return is_consumed;
 }
 
@@ -515,62 +504,13 @@ spi_keystroke_from_x_key_event (XKeyEven
   return key_event;	
 }
 
-
-static gboolean
-spi_check_key_event (SpiDeviceEventController *controller)
-{
-	static gboolean initialized = FALSE;
-	XEvent *x_event = g_new0 (XEvent, 1);
-	XKeyEvent *x_key_event;
-	gboolean is_consumed = FALSE;
-	Accessibility_DeviceEvent key_event;
-	static CORBA_Environment ev;
-
-	if (!initialized)
-	{
-	  initialized = TRUE;
-	  CORBA_exception_init (&ev);
-	}
-
-	while (XPending(spi_get_display ()))
-	  {
-	    XNextEvent (spi_get_display (), x_event);
-	    if (XFilterEvent (x_event, None)) continue;	  
-	    if (x_event->type == KeyPress || x_event->type == KeyRelease)
-	      {
-	        key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) x_event);
-	        /* relay to listeners, and decide whether to consume it or not */
-	        is_consumed = spi_notify_keylisteners (controller->key_listeners, &key_event, CORBA_TRUE, &ev);
-	      }
-	    else
-	      {
-#ifdef SPI_KEYEVENT_DEBUG
-	        fprintf (stderr, "other event, type %d\n", (int) x_event->type);
-#endif
-	      }
-
-	    if (is_consumed)
-	      {
-	        XAllowEvents (spi_get_display (), AsyncKeyboard, CurrentTime);
-	      }
-	    else
-	      {
-	        XAllowEvents (spi_get_display (), ReplayKeyboard, CurrentTime);
-	      }
-	  }
-	XUngrabKey (spi_get_display (), AnyKey, AnyModifier, root_window);
-
-	return spi_controller_grab_keyboard (controller);
-}
-
 static gboolean
 spi_controller_grab_keyboard (SpiDeviceEventController *controller)
 {
-  GList *maskList = controller->keygrabs_list;
-  int i;
-  int last_mask;
-  last_mask = g_list_length (maskList);
+  GList *l;
 
+  g_return_val_if_fail (controller != NULL, FALSE);
+
 /*
  * masks known to work with default RH 7.1: 
  * 0 (no mods), LockMask, Mod1Mask, Mod2Mask, ShiftMask,
@@ -580,30 +520,29 @@ spi_controller_grab_keyboard (SpiDeviceE
  *
  * ControlMask grabs are broken, must be in use already
  */
-	
-  for (i=0; i < last_mask; ++i)
+
+  for (l = controller->keygrabs_list; l; l = l->next)
     {
-      DEControllerGrabMask * grab_mask
-		= (DEControllerGrabMask *) g_list_nth_data (maskList, i);
-      unsigned long maskVal = 0xFFFFFFFF;
-      int           keyVal = AnyKey;
-      if (grab_mask)
-        {
-	  maskVal = (unsigned long) grab_mask->modmask;
-	  keyVal =  grab_mask->keyval;
-        }
+      DEControllerGrabMask *grab_mask = l->data;
+
+      g_assert (grab_mask != NULL);
+
 #ifdef SPI_DEBUG
-      fprintf (stderr, "mask=%lx\n", maskVal);
+      fprintf (stderr, "mask=%lx %lx\n",
+	       (long int) grab_mask->keyval,
+	       (long int) grab_mask->modmask);
 #endif
-      XGrabKey (spi_get_display (),
-		keyVal, 
-		maskVal,
+
+      XGrabKey (GDK_DISPLAY (),
+		grab_mask->keyval,
+		grab_mask->modmask,
 		root_window,
 		True,
 		GrabModeAsync,
 		GrabModeAsync);
 	  /* TODO: check call for errors and return FALSE if error occurs */
     } 
+
   return TRUE;
 }
 
@@ -613,7 +552,10 @@ spi_controller_grab_keyboard (SpiDeviceE
 static void
 spi_device_event_controller_object_finalize (GObject *object)
 {
+  SpiDeviceEventController *controller;
 
+  controller = SPI_DEVICE_EVENT_CONTROLLER (object);
+
 #ifdef SPI_DEBUG
   fprintf(stderr, "spi_device_event_controller_object_finalize called\n");
 #endif
@@ -627,13 +569,13 @@ spi_device_event_controller_object_final
  *     method implementation
  */
 static void
-impl_register_keystroke_listener (PortableServer_Servant     servant,
+impl_register_keystroke_listener (PortableServer_Servant                  servant,
 				  const Accessibility_DeviceEventListener l,
-				  const Accessibility_KeySet *keys,
+				  const Accessibility_KeySet             *keys,
 				  const Accessibility_ControllerEventMask mask,
-				  const Accessibility_KeyEventTypeSeq *type,
-				  const Accessibility_EventListenerMode *mode,
-				  CORBA_Environment         *ev)
+				  const Accessibility_KeyEventTypeSeq    *type,
+				  const Accessibility_EventListenerMode  *mode,
+				  CORBA_Environment                      *ev)
 {
   SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
 	  bonobo_object_from_servant (servant));
@@ -646,59 +588,69 @@ impl_register_keystroke_listener (Portab
   spi_controller_register_device_listener (controller, (DEControllerListener *) dec_listener, ev);
 }
 
+
+typedef struct {
+	CORBA_Environment       *ev;
+	DEControllerKeyListener *key_listener;
+} RemoveKeyListenerClosure;
+
+static SpiReEnterantContinue
+remove_key_listener_cb (GList * const *list,
+			gpointer       user_data)
+{
+  DEControllerKeyListener  *key_listener = (*list)->data;
+  RemoveKeyListenerClosure *ctx = user_data;
+
+  if (CORBA_Object_is_equivalent (ctx->key_listener->listener.object,
+				  key_listener->listener.object, ctx->ev))
+    {
+      spi_re_enterant_list_delete_link (list);
+      spi_dec_key_listener_free (key_listener, ctx->ev);
+    }
+
+  return SPI_RE_ENTERANT_CONTINUE;
+}
+
 /*
  * CORBA Accessibility::DeviceEventController::deregisterKeystrokeListener
  *     method implementation
  */
 static void
-impl_deregister_keystroke_listener (PortableServer_Servant     servant,
+impl_deregister_keystroke_listener (PortableServer_Servant                  servant,
 				    const Accessibility_DeviceEventListener l,
-				    const Accessibility_KeySet *keys,
+				    const Accessibility_KeySet             *keys,
 				    const Accessibility_ControllerEventMask mask,
-				    const Accessibility_KeyEventTypeSeq *type,
-				    CORBA_Environment         *ev)
+				    const Accessibility_KeyEventTypeSeq    *type,
+				    CORBA_Environment                      *ev)
 {
-	SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
-		bonobo_object_from_servant (servant));
-	DEControllerKeyListener *key_listener = spi_dec_key_listener_new (l,
-									  keys,
-									  mask,
-									  type,
-									  NULL,
-									  ev);
+  DEControllerKeyListener  *key_listener;
+  RemoveKeyListenerClosure  ctx;
+  SpiDeviceEventController *controller;
+
+  controller = SPI_DEVICE_EVENT_CONTROLLER (bonobo_object (servant));
+
+  key_listener = spi_dec_key_listener_new (l, keys, mask, type, NULL, ev);
+
 #ifdef SPI_DEREGISTER_DEBUG
-	fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
-		 (void *) l, (unsigned long) mask->value);
+  fprintf (stderr, "deregistering keystroke listener %p with maskVal %lu\n",
+	   (void *) l, (unsigned long) mask->value);
 #endif
-	spi_controller_deregister_device_listener(controller,
-					      (DEControllerListener *) key_listener,
-					      ev);
-	spi_dec_key_listener_free (key_listener, ev);
-}
 
-/*
- * CORBA Accessibility::DeviceEventController::registerMouseListener
- *     method implementation
- */
-/*
-static void
-impl_register_mouse_listener (PortableServer_Servant     servant,
-			      const Accessibility_MouseListener *l,
-			      CORBA_Environment         *ev)
-{
-	SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
-		bonobo_object_from_servant (servant));
-#ifdef SPI_DEBUG
-	fprintf (stderr, "registering mouse listener %p\n", l);
-#endif
-	spi_controller_register_device_listener(controller, DEVICE_TYPE_MOUSE, l, keys, mask, ev);
+  spi_controller_deregister_global_keygrabs (controller, key_listener);
+
+  ctx.ev = ev;
+  ctx.key_listener = key_listener;
+
+  spi_re_enterant_list_foreach (&controller->key_listeners,
+				remove_key_listener_cb, &ctx);
+
+  spi_dec_key_listener_free (key_listener, ev);
 }
-*/
 
 static KeyCode
 keycode_for_keysym (long keysym)
 {
-  return XKeysymToKeycode (spi_get_display (), (KeySym) keysym);
+  return XKeysymToKeycode (GDK_DISPLAY (), (KeySym) keysym);
 }
 
 #define SPI_DEBUG
@@ -715,6 +667,7 @@ impl_generate_keyboard_event (PortableSe
 			      CORBA_Environment          *ev)
 {
   long key_synth_code;
+
 #ifdef SPI_DEBUG
   fprintf (stderr, "synthesizing keystroke %ld, type %d\n", (long) keycode, (int) synth_type);
 #endif
@@ -732,17 +685,20 @@ impl_generate_keyboard_event (PortableSe
   switch (synth_type)
     {
       case Accessibility_KEY_PRESS:
-	  XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime);
+	  XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime);
 	  break;
       case Accessibility_KEY_PRESSRELEASE:
-	  XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, True, CurrentTime);
+	  XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, True, CurrentTime);
       case Accessibility_KEY_RELEASE:
-	  XTestFakeKeyEvent (spi_get_display (), (unsigned int) keycode, False, CurrentTime);
+	  XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) keycode, False, CurrentTime);
 	  break;
       case Accessibility_KEY_SYM:
 	  key_synth_code = keycode_for_keysym (keycode);
-	  XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, True, CurrentTime);
-	  XTestFakeKeyEvent (spi_get_display (), (unsigned int) key_synth_code, False, CurrentTime);
+	  XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, True, CurrentTime);
+	  XTestFakeKeyEvent (GDK_DISPLAY (), (unsigned int) key_synth_code, False, CurrentTime);
+	  break;
+      case Accessibility_KEY_STRING:
+	  fprintf (stderr, "Not yet implemented\n");
 	  break;
    }
 }
@@ -756,85 +712,121 @@ impl_generate_mouse_event (PortableServe
 			   CORBA_Environment     *ev)
 {
 #ifdef SPI_DEBUG
-  fprintf (stderr, "generating mouse %s event at %ld, %ld\n", eventName, x, y);
+  fprintf (stderr, "generating mouse %s event at %ld, %ld\n",
+	   eventName, (long int) x, (long int) y);
 #endif
+  g_warning ("not yet implemented");
 }
 
 /* Accessibility::DeviceEventController::notifyListenersSync */
 static CORBA_boolean
-impl_notify_listeners_sync(PortableServer_Servant     servant,
-			   const Accessibility_DeviceEvent *event,
-			   CORBA_Environment         *ev)
+impl_notify_listeners_sync (PortableServer_Servant           servant,
+			    const Accessibility_DeviceEvent *event,
+			    CORBA_Environment               *ev)
 {
   SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
-                                         bonobo_object_from_servant (servant));
+    bonobo_object_from_servant (servant));
 #ifdef SPI_DEBUG
-  g_print ("notifylistening listeners synchronously: controller %x, event id %d\n",
-	   (void *) controller, (int) event->id);
+  g_print ("notifylistening listeners synchronously: controller %p, event id %d\n",
+	   controller, (int) event->id);
 #endif
-  return (spi_notify_keylisteners (controller->key_listeners, event, CORBA_FALSE, ev) ?
-	  CORBA_TRUE : CORBA_FALSE); 
+  return spi_notify_keylisteners (&controller->key_listeners, event, CORBA_FALSE, ev) ?
+	  CORBA_TRUE : CORBA_FALSE; 
 }
 
 /* Accessibility::DeviceEventController::notifyListenersAsync */
 static void
-impl_notify_listeners_async (PortableServer_Servant     servant,
+impl_notify_listeners_async (PortableServer_Servant           servant,
 			     const Accessibility_DeviceEvent *event,
-			     CORBA_Environment         *ev)
+			     CORBA_Environment               *ev)
 {
-  SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER(
-	                                 bonobo_object_from_servant (servant));
+  SpiDeviceEventController *controller = SPI_DEVICE_EVENT_CONTROLLER (
+    bonobo_object_from_servant (servant));
 #ifdef SPI_DEBUG
   fprintf (stderr, "notifying listeners asynchronously\n");
 #endif
-  spi_notify_keylisteners (controller->key_listeners, event, CORBA_FALSE, ev); 
+  spi_notify_keylisteners (&controller->key_listeners, event, CORBA_FALSE, ev); 
 }
 
 static void
 spi_device_event_controller_class_init (SpiDeviceEventControllerClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
-        POA_Accessibility_DeviceEventController__epv *epv = &klass->epv;
-        spi_device_event_controller_parent_class = g_type_class_peek_parent (klass);
-
-        object_class->finalize = spi_device_event_controller_object_finalize;
-
-        epv->registerKeystrokeListener = impl_register_keystroke_listener;
-        epv->deregisterKeystrokeListener = impl_deregister_keystroke_listener;
-/*        epv->registerMouseListener = impl_register_mouse_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;
-	klass->check_key_event = spi_check_key_event;
+  GObjectClass * object_class = (GObjectClass *) klass;
+  POA_Accessibility_DeviceEventController__epv *epv = &klass->epv;
+
+  spi_device_event_controller_parent_class = g_type_class_peek_parent (klass);
+  
+  object_class->finalize = spi_device_event_controller_object_finalize;
+	
+  epv->registerKeystrokeListener   = impl_register_keystroke_listener;
+  epv->deregisterKeystrokeListener = impl_deregister_keystroke_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;
 }
 
 static void
 spi_device_event_controller_init (SpiDeviceEventController *device_event_controller)
 {
-  device_event_controller->key_listeners = NULL;
+  device_event_controller->key_listeners   = NULL;
   device_event_controller->mouse_listeners = NULL;
-  device_event_controller->keygrabs_list = NULL;
-  kbd_registered = spi_controller_register_with_devices (device_event_controller);
+  device_event_controller->keygrabs_list   = NULL;
+
+  /*
+   * TODO: fixme, this module makes the foolish assumption that
+   * registryd uses the same display as the apps, and the the DISPLAY
+   * environment variable is set.
+   */
+  gdk_init (NULL, NULL);
+  
+  spi_controller_register_with_devices (device_event_controller);
 }
 
-gboolean
-spi_device_event_controller_check_key_event (SpiDeviceEventController *controller)
+static void
+spi_device_event_controller_forward_key_event (SpiDeviceEventController *controller,
+					       const XEvent             *event)
 {
-  SpiDeviceEventControllerClass *klass = SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS (controller);
-  if (klass->check_key_event)
-	return (klass->check_key_event) (controller);
-  return FALSE;
+  gboolean is_consumed = FALSE;
+  CORBA_Environment ev;
+  Accessibility_DeviceEvent key_event;
+
+  g_assert (event->type == KeyPress || event->type == KeyRelease);
+
+  CORBA_exception_init (&ev);
+
+  g_warning ("Got key event");
+	    
+  key_event = spi_keystroke_from_x_key_event ((XKeyEvent *) event);
+  /* relay to listeners, and decide whether to consume it or not */
+  is_consumed = spi_notify_keylisteners (
+    &controller->key_listeners, &key_event, CORBA_TRUE, &ev);
+
+  CORBA_exception_free (&ev);
+
+  if (is_consumed)
+    {
+      XAllowEvents (GDK_DISPLAY (), AsyncKeyboard, CurrentTime);
+    }
+  else
+    {
+      XAllowEvents (GDK_DISPLAY (), ReplayKeyboard, CurrentTime);
+    }
+
+  /* FIXME - this looks strange and inefficient */
+  XUngrabKey (GDK_DISPLAY (), AnyKey, AnyModifier, root_window);
+  spi_controller_grab_keyboard (controller);
 }
 
 SpiDeviceEventController *
-spi_device_event_controller_new (void *registryp)
+spi_device_event_controller_new (SpiRegistry *registry)
 {
-  BonoboObject *registry = (BonoboObject *) registryp;	
   SpiDeviceEventController *retval = g_object_new (
-	  SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL);
-  retval->registry = registry;
-  bonobo_object_ref (registry);
+    SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL);
+
+  retval->registry = SPI_REGISTRY (bonobo_object_ref (
+	  BONOBO_OBJECT (registry)));
+
   return retval;
 }
 
Index: registryd/deviceeventcontroller.h
===================================================================
RCS file: /cvs/gnome/at-spi/registryd/deviceeventcontroller.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 deviceeventcontroller.h
--- registryd/deviceeventcontroller.h	2001/12/15 22:54:00	1.10
+++ registryd/deviceeventcontroller.h	2002/01/09 12:13:35
@@ -27,6 +27,10 @@
 #include <libspi/Accessibility.h>
 #include <libspi/keystrokelistener.h>
 
+typedef struct _SpiDeviceEventController SpiDeviceEventController;
+
+#include "registry.h"
+
 G_BEGIN_DECLS
 
 #define SPI_DEVICE_EVENT_CONTROLLER_TYPE        (spi_device_event_controller_get_type ())
@@ -36,23 +40,23 @@ G_BEGIN_DECLS
 #define SPI_IS_DEVICE_EVENT_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_DEVICE_EVENT_CONTROLLER_TYPE))
 #define SPI_DEVICE_EVENT_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPI_DEVICE_EVENT_CONTROLLER_TYPE, SpiDeviceEventControllerClass))
 
-typedef struct {
+struct _SpiDeviceEventController {
   BonoboObject parent;
-  void  *registry;
-  GList *key_listeners;
-  GList *mouse_listeners;
-  GList *keygrabs_list;
-} SpiDeviceEventController;
 
+  SpiRegistry *registry;
+  GList       *key_listeners;
+  GList       *mouse_listeners;
+  GList       *keygrabs_list;
+};
+
 typedef struct {
   BonoboObjectClass parent_class;
+
   POA_Accessibility_DeviceEventController__epv epv;
-  gboolean (*check_key_event) (SpiDeviceEventController *controller);
 } SpiDeviceEventControllerClass;
 
 GType                     spi_device_event_controller_get_type        (void);
-SpiDeviceEventController *spi_device_event_controller_new             (void *registry);
-gboolean                  spi_device_event_controller_check_key_event (SpiDeviceEventController *controller);
+SpiDeviceEventController *spi_device_event_controller_new             (SpiRegistry  *registry);
 
 G_END_DECLS
 
Index: registryd/registry-main.c
===================================================================
RCS file: /cvs/gnome/at-spi/registryd/registry-main.c,v
retrieving revision 1.10
diff -u -p -u -r1.10 registry-main.c
--- registryd/registry-main.c	2001/12/07 16:43:30	1.10
+++ registryd/registry-main.c	2002/01/09 12:13:35
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #endif
 
+#include <gdk/gdk.h>
 #include <libbonobo.h>
 #include <glib/gmain.h>
 #include "registry.h"
@@ -59,7 +60,6 @@ main (int argc, char **argv)
 #ifdef AT_SPI_DEBUG
       fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
 #endif
-      g_timeout_add_full (G_PRIORITY_HIGH_IDLE, 200, registry->kbd_event_hook, registry, NULL);
       bonobo_main ();
     }
 
Index: registryd/registry.c
===================================================================
RCS file: /cvs/gnome/at-spi/registryd/registry.c,v
retrieving revision 1.35
diff -u -p -u -r1.35 registry.c
--- registryd/registry.c	2002/01/08 09:11:46	1.35
+++ registryd/registry.c	2002/01/09 12:13:35
@@ -30,6 +30,7 @@
 #endif
 
 #include <bonobo/bonobo-exception.h>
+#include "../libspi/spi-private.h"
 #include "registry.h"
 
 /* Our parent GObject type  */
@@ -63,8 +64,6 @@ typedef struct {
   EventTypeCategory event_type_cat;
 } SpiListenerStruct;
 
-/* static function prototypes */
-static gboolean _device_event_controller_hook (gpointer source);
 
 SpiListenerStruct *
 spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment *ev)
@@ -347,7 +346,7 @@ impl_accessibility_registry_register_glo
     }
 }
 
-static void
+static SpiReEnterantContinue
 remove_listener_cb (GList * const *list, gpointer user_data)
 {
   SpiListenerStruct *ls = (SpiListenerStruct *) (*list)->data;
@@ -363,6 +362,8 @@ remove_listener_cb (GList * const *list,
     }
 
   CORBA_exception_free (&ev);
+
+  return SPI_RE_ENTERANT_CONTINUE;
 }
 
 /*
@@ -407,7 +408,7 @@ impl_accessibility_registry_deregister_g
   parse_event_type (&etype, (char *) event_name);
 
   spi_re_enterant_list_foreach (get_listener_list (registry, etype.type_cat),
-			    remove_listener_cb, listener);
+				remove_listener_cb, listener);
 }
 

@@ -503,7 +504,7 @@ typedef struct {
   Accessibility_Event e_out;
 } NotifyContext;
 
-static void
+static SpiReEnterantContinue
 notify_listeners_cb (GList * const *list, gpointer user_data)
 {
   SpiListenerStruct *ls;
@@ -531,7 +532,9 @@ notify_listeners_cb (GList * const *list
       
       ctx->e_out.source = bonobo_object_dup_ref (ctx->source, ctx->ev);
       if (BONOBO_EX (ctx->ev))
-	      return;
+        {
+          return SPI_RE_ENTERANT_CONTINUE;;
+	}
 
       if ((*list) && (*list)->data == ls)
         {
@@ -549,6 +552,8 @@ notify_listeners_cb (GList * const *list
           bonobo_object_release_unref (ctx->e_out.source, ctx->ev);
 	}
     }  
+
+  return SPI_RE_ENTERANT_CONTINUE;
 }
 
 static void
@@ -582,37 +587,28 @@ impl_registry_notify_event (PortableServ
     }
 }
 
-static gboolean
-_device_event_controller_hook (gpointer p)
-{
-    SpiRegistry *registry = (SpiRegistry *)p;
-    SpiDeviceEventController *controller = registry->device_event_controller;
-    if (controller)
-	spi_device_event_controller_check_key_event (controller);
-    return TRUE;
-}
 
 static void
 spi_registry_class_init (SpiRegistryClass *klass)
 {
-        GObjectClass * object_class = (GObjectClass *) klass;
-        POA_Accessibility_Registry__epv *epv = &klass->epv;
+  GObjectClass * object_class = (GObjectClass *) klass;
+  POA_Accessibility_Registry__epv *epv = &klass->epv;
 
-        spi_registry_parent_class = g_type_class_ref (SPI_LISTENER_TYPE);
-
-        object_class->finalize = spi_registry_object_finalize;
-
-        epv->registerApplication = impl_accessibility_registry_register_application;
-        epv->deregisterApplication = impl_accessibility_registry_deregister_application;
-        epv->registerGlobalEventListener = impl_accessibility_registry_register_global_event_listener;
-        epv->deregisterGlobalEventListener = impl_accessibility_registry_deregister_global_event_listener;
-        epv->deregisterGlobalEventListenerAll = impl_accessibility_registry_deregister_global_event_listener_all;
-        epv->getDeviceEventController = impl_accessibility_registry_get_device_event_controller;
-        epv->getDesktopCount = impl_accessibility_registry_get_desktop_count;
-        epv->getDesktop = impl_accessibility_registry_get_desktop;
-        epv->getDesktopList = impl_accessibility_registry_get_desktop_list;
-
-        ((SpiListenerClass *) klass)->epv.notifyEvent = impl_registry_notify_event;
+  spi_registry_parent_class = g_type_class_ref (SPI_LISTENER_TYPE);
+  
+  object_class->finalize = spi_registry_object_finalize;
+  
+  epv->registerApplication = impl_accessibility_registry_register_application;
+  epv->deregisterApplication = impl_accessibility_registry_deregister_application;
+  epv->registerGlobalEventListener = impl_accessibility_registry_register_global_event_listener;
+  epv->deregisterGlobalEventListener = impl_accessibility_registry_deregister_global_event_listener;
+  epv->deregisterGlobalEventListenerAll = impl_accessibility_registry_deregister_global_event_listener_all;
+  epv->getDeviceEventController = impl_accessibility_registry_get_device_event_controller;
+  epv->getDesktopCount = impl_accessibility_registry_get_desktop_count;
+  epv->getDesktop = impl_accessibility_registry_get_desktop;
+  epv->getDesktopList = impl_accessibility_registry_get_desktop_list;
+  
+  ((SpiListenerClass *) klass)->epv.notifyEvent = impl_registry_notify_event;
 }
 
 static void
@@ -623,7 +619,6 @@ spi_registry_init (SpiRegistry *registry
   registry->toolkit_listeners = NULL;
   registry->desktop = spi_desktop_new ();
   registry->device_event_controller = NULL;
-  registry->kbd_event_hook = _device_event_controller_hook;
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiRegistry,
@@ -634,7 +629,7 @@ BONOBO_TYPE_FUNC_FULL (SpiRegistry,
 SpiRegistry *
 spi_registry_new (void)
 {
-    SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL);
-    bonobo_object_set_immortal (BONOBO_OBJECT (retval), TRUE);
-    return retval;
+  SpiRegistry *retval = g_object_new (SPI_REGISTRY_TYPE, NULL);
+  bonobo_object_set_immortal (BONOBO_OBJECT (retval), TRUE);
+  return retval;
 }
Index: registryd/registry.h
===================================================================
RCS file: /cvs/gnome/at-spi/registryd/registry.h,v
retrieving revision 1.13
diff -u -p -u -r1.13 registry.h
--- registryd/registry.h	2001/12/12 16:08:46	1.13
+++ registryd/registry.h	2002/01/09 12:13:35
@@ -26,6 +26,8 @@
 #include <glib/gmain.h>
 #include <libspi/listener.h>
 
+typedef struct _SpiRegistry SpiRegistry;
+
 #include "desktop.h"
 #include "deviceeventcontroller.h"
 
@@ -37,15 +39,14 @@ G_BEGIN_DECLS
 #define SPI_IS_REGISTRY(o)       (G_TYPE_CHECK__INSTANCE_TYPE ((o), SPI_REGISTRY_TYPE))
 #define SPI_IS_REGISTRY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPI_REGISTRY_TYPE))
 
-typedef struct {
+struct _SpiRegistry {
   SpiListener parent;
   GList *object_listeners;
   GList *window_listeners;
   GList *toolkit_listeners;
   SpiDeviceEventController *device_event_controller;
   SpiDesktop *desktop;
-  gboolean (*kbd_event_hook) (gpointer source);
-} SpiRegistry;
+};
 
 typedef struct {
         SpiListenerClass parent_class;
Index: test/keysynth-demo.c
===================================================================
RCS file: /cvs/gnome/at-spi/test/keysynth-demo.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 keysynth-demo.c
--- test/keysynth-demo.c	2002/01/01 22:35:33	1.14
+++ test/keysynth-demo.c	2002/01/09 12:13:35
@@ -319,7 +319,7 @@ button_exit (GtkButton *notused, void *a
 }
 
 static SPIBoolean
-is_command_key (AccessibleKeystroke *key, void *user_data)
+is_command_key (const AccessibleKeystroke *key, void *user_data)
 {
   switch (key->keyID)
     {
@@ -332,7 +332,7 @@ is_command_key (AccessibleKeystroke *key
 }
 
 static SPIBoolean
-switch_callback (AccessibleKeystroke *key, void *user_data)
+switch_callback (const AccessibleKeystroke *key, void *user_data)
 {
   static SPIBoolean is_down = FALSE;
 
Index: test/simple-at.c
===================================================================
RCS file: /cvs/gnome/at-spi/test/simple-at.c,v
retrieving revision 1.31
diff -u -p -u -r1.31 simple-at.c
--- test/simple-at.c	2002/01/08 09:11:47	1.31
+++ test/simple-at.c	2002/01/09 12:13:35
@@ -28,12 +28,12 @@
 #include "../util/mag_client.h"
 #include "../cspi/spi-private.h" /* A hack for now */
 
-static void report_focus_event    (AccessibleEvent *event, void *user_data);
-static void report_generic_event  (AccessibleEvent *event, void *user_data);
-static void report_button_press   (AccessibleEvent *event, void *user_data);
-static void check_property_change (AccessibleEvent *event, void *user_data);
-static SPIBoolean report_command_key_event  (AccessibleKeystroke *stroke, void *user_data);
-static SPIBoolean report_ordinary_key_event (AccessibleKeystroke *stroke, void *user_data);
+static void report_focus_event    (const AccessibleEvent *event, void *user_data);
+static void report_generic_event  (const AccessibleEvent *event, void *user_data);
+static void report_button_press   (const AccessibleEvent *event, void *user_data);
+static void check_property_change (const AccessibleEvent *event, void *user_data);
+static SPIBoolean report_command_key_event  (const AccessibleKeystroke *stroke, void *user_data);
+static SPIBoolean report_ordinary_key_event (const AccessibleKeystroke *stroke, void *user_data);
 static void get_environment_vars (void);
 
 static int _festival_init ();
@@ -242,7 +242,7 @@ report_focussed_accessible (Accessible *
 }
 
 void
-report_focus_event (AccessibleEvent *event, void *user_data)
+report_focus_event (const AccessibleEvent *event, void *user_data)
 {
   char *s;
 
@@ -259,13 +259,13 @@ report_focus_event (AccessibleEvent *eve
 }
 
 void
-report_generic_event (AccessibleEvent *event, void *user_data)
+report_generic_event (const AccessibleEvent *event, void *user_data)
 {
   fprintf (stderr, "%s event received\n", event->type);
 }
 
 void
-report_button_press (AccessibleEvent *event, void *user_data)
+report_button_press (const AccessibleEvent *event, void *user_data)
 {
   char *s;
 
@@ -281,7 +281,7 @@ report_button_press (AccessibleEvent *ev
 }
 
 void
-check_property_change (AccessibleEvent *event, void *user_data)
+check_property_change (const AccessibleEvent *event, void *user_data)
 {
   AccessibleSelection *selection = Accessible_getSelection (event->source);
   int n_selections;
@@ -335,7 +335,7 @@ simple_at_exit ()
 }
 
 static SPIBoolean
-is_command_key (AccessibleKeystroke *key)
+is_command_key (const AccessibleKeystroke *key)
 {
   switch (key->keyID)
     {
@@ -359,7 +359,7 @@ is_command_key (AccessibleKeystroke *key
 }
 
 static SPIBoolean
-report_command_key_event (AccessibleKeystroke *key, void *user_data)
+report_command_key_event (const AccessibleKeystroke *key, void *user_data)
 {
   fprintf (stderr, "Command KeyEvent %s%c (keycode %d); string=%s; time=%lx\n",
 	  (key->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
@@ -373,7 +373,7 @@ report_command_key_event (AccessibleKeys
 

 static SPIBoolean
-report_ordinary_key_event (AccessibleKeystroke *key, void *user_data)
+report_ordinary_key_event (const AccessibleKeystroke *key, void *user_data)
 {
   fprintf (stderr, "Received key event:\tsym %ld\n\tmods %x\n\tcode %d\n\tstring=\'%s\'\n\ttime %lx\n",
 	   (long) key->keyID,
Index: test/test-simple.c
===================================================================
RCS file: /cvs/gnome/at-spi/test/test-simple.c,v
retrieving revision 1.16
diff -u -p -u -r1.16 test-simple.c
--- test/test-simple.c	2002/01/08 09:11:47	1.16
+++ test/test-simple.c	2002/01/09 12:13:36
@@ -611,8 +611,8 @@ test_misc (void)
 }
 
 static void
-global_listener_cb (AccessibleEvent     *event,
-		    void                *user_data)
+global_listener_cb (const AccessibleEvent *event,
+		    void                  *user_data)
 {
 	TestWindow *win = user_data;
 	Accessible *desktop;
@@ -643,6 +643,48 @@ global_listener_cb (AccessibleEvent     
 	validate_accessible (event->source, TRUE, TRUE);
 }
 
+static SPIBoolean
+key_listener_cb (const AccessibleKeystroke *stroke,
+		 void                      *user_data)
+{
+	AccessibleKeystroke *s = user_data;
+
+	*s = *stroke;
+
+	g_warning ("Key listener callback");
+
+	return FALSE;
+}
+
+static void
+test_keylisteners (void)
+{
+	AccessibleKeystroke stroke;
+	AccessibleKeystrokeListener *key_listener;
+
+	key_listener = SPI_createAccessibleKeystrokeListener (
+		key_listener_cb, &stroke);
+
+	g_assert (SPI_registerAccessibleKeystrokeListener (
+		key_listener, SPI_KEYSET_ALL_KEYS, 0,
+		SPI_KEY_PRESSED | SPI_KEY_RELEASED,
+		SPI_KEYLISTENER_CANCONSUME));
+
+	memset (&stroke, 0, sizeof (AccessibleKeystroke));
+
+	g_assert (SPI_generateKeyboardEvent (33, "!", SPI_KEY_PRESSRELEASE));
+
+	while (stroke.type == 0)
+		g_main_iteration (TRUE);
+
+	g_assert (!strcmp (stroke.keystring, "!"));
+	g_assert (stroke.type == SPI_KEY_PRESSRELEASE);
+
+	g_assert (SPI_deregisterAccessibleKeystrokeListener (key_listener, 0));
+
+	AccessibleKeystrokeListener_unref (key_listener);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -670,6 +712,7 @@ main (int argc, char **argv)
 	test_roles ();
 	test_misc ();
 	test_desktop ();
+	test_keylisteners ();
 
 	win = create_test_window ();
 

-- 
 mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]