Partial fix for 84261, we now report mouse motion events to listeners who
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Tue, 25 Jun 2002 20:38:05 +0000 (20:38 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Tue, 25 Jun 2002 20:38:05 +0000 (20:38 +0000)
register for events of type "mouse:rel".

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

ChangeLog
cspi/spi_registry.c
registryd/deviceeventcontroller.c
registryd/registry.c
test/event-listener-test.c

index 0aa31f8..71ca1b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2002-06-25  Bill Haneman  <bill.haneman@sun.com>
+
+       * registryd/deviceeventcontroller.c: partial fix for 84261
+       (spi_dec_poll_mouse_idle):
+       New method, a timeout which checks to see if the mouse
+       has moved.
+       (spi_dec_poll_mouse_moving):
+       A timeout to be called when mouse motion is underway.
+       (spi_dec_poll_mouse_moved):
+       A method which fires an event if the mouse has moved, and reports
+       whether or not it did so. 
+       (spi_dec_init_mouse_listener):
+       A method which sets up the timeouts above.
+       (spi_device_event_controller_new):
+       Now calls spi_dec_init_mouse_listener.
+
+       * registryd/registry.c:
+       (spi_registry_init):
+       Now we initialize the device event controller when the registry is
+       initialized, instead of waiting until a client has requested a key
+       event notification; this is because we need the event controller
+       for mouse events, but the mouse event registration API is a
+       "registry" call and doesn't explicitly call the 
+       deviceeventcontroller.
+       We now report mouse motion events with a 100 ms idle latency and
+       a 20 ms granularity when motion is in progress.
+
+       * test/event-listener-test.c:
+       (main):
+       We now register the "detail listener" for events of type 
+       "mouse:rel" and "mouse:abs" (Note, mouse-abs events generally are
+       delivered only for the first mouse event received, and thereafter
+       "mouse:abs" events are delivered.)
+
+       * cspi/spi_registry.c:
+       DOCS: Documented the above mouse event typestrings.
+       
 2002-06-21  Bill Haneman  <bill.haneman@sun.com>
 
        Happy Summer Solstice...
index 7e86360..7694a99 100644 (file)
  *            window:unshade
  *            window:restyle
  *
+ *  (other events)
+ *
+ *            focus:
+ *            mouse:abs
+ *            mouse:rel
+ *            mouse:b1p
+ *            mouse:b1r
+ *            mouse:b2p
+ *            mouse:b2r
+ *            mouse:b3p
+ *            mouse:b3r
+ *
  * 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 129390a..d843209 100644 (file)
@@ -50,6 +50,7 @@
 /* A pointer to our parent object class */
 static GObjectClass *spi_device_event_controller_parent_class;
 static int spi_error_code = 0;
+static GdkPoint *last_mouse_pos = NULL;
 
 int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
 
@@ -95,6 +96,9 @@ static void     spi_deregister_controller_key_listener (SpiDEController
                                                        CORBA_Environment       *ev);
 
 static gboolean spi_clear_error_state (void);
+static gboolean spi_dec_poll_mouse_moved (gpointer data);
+static gboolean spi_dec_poll_mouse_moving (gpointer data);
+static gboolean spi_dec_poll_mouse_idle (gpointer data);
 
 #define spi_get_display() GDK_DISPLAY()
 
@@ -142,6 +146,75 @@ spi_grab_mask_compare_values (gconstpointer p1, gconstpointer p2)
     }
 }
 
+static gboolean
+spi_dec_poll_mouse_moved (gpointer data)
+{
+  SpiRegistry *registry = SPI_REGISTRY (data);
+  CORBA_Environment ev;
+  Accessibility_Event e;
+  Window root_return, child_return;
+  int win_x_return,win_y_return;
+  int x, y;
+  unsigned int mask_return;
+  Display *display = spi_get_display ();
+  if (last_mouse_pos == NULL) {
+         last_mouse_pos = g_new0 (GdkPoint, 1);
+         last_mouse_pos->x = 0;
+         last_mouse_pos->y = 0;
+         e.type = g_strdup ("mouse:abs");
+  } else {
+         e.type = g_strdup ("mouse:rel");
+  }
+  if (display != NULL)
+         XQueryPointer(display, DefaultRootWindow (display),
+               &root_return, &child_return,
+               &x, &y,
+               &win_x_return, &win_y_return, &mask_return);
+  if (x != last_mouse_pos->x || y != last_mouse_pos->y) {
+         e.source = BONOBO_OBJREF (registry->desktop);
+         e.detail1 = x - last_mouse_pos->x;
+         e.detail2 = y - last_mouse_pos->y;
+         CORBA_exception_init (&ev);
+         last_mouse_pos->x = x;
+         last_mouse_pos->y = y;
+         Accessibility_Registry_notifyEvent (BONOBO_OBJREF (registry),
+                                             &e,
+                                             &ev);
+         return TRUE;
+  }
+  return FALSE;
+}
+
+static gboolean
+spi_dec_poll_mouse_idle (gpointer data)
+{
+  if (! spi_dec_poll_mouse_moved (data)) 
+    return TRUE;
+  else
+    {
+      g_timeout_add (20, spi_dec_poll_mouse_moving, data);         
+      return FALSE;        
+    }
+}
+
+static gboolean
+spi_dec_poll_mouse_moving (gpointer data)
+{
+  if (spi_dec_poll_mouse_moved (data))
+    return TRUE;
+  else
+    {
+      g_timeout_add (100, spi_dec_poll_mouse_idle, data);          
+      return FALSE;
+    }
+}
+
+static void
+spi_dec_init_mouse_listener (SpiRegistry *registry)
+{
+  g_timeout_add (100, spi_dec_poll_mouse_idle, registry);
+}
+
 static DEControllerKeyListener *
 spi_dec_key_listener_new (CORBA_Object                            l,
                          const Accessibility_KeySet             *keys,
@@ -1173,6 +1246,9 @@ spi_device_event_controller_new (SpiRegistry *registry)
   retval->registry = SPI_REGISTRY (bonobo_object_ref (
          BONOBO_OBJECT (registry)));
 
+  spi_dec_init_mouse_listener (registry);
+  /* TODO: kill mouse listener on finalize */
+  
   return retval;
 }
 
index 33afabc..c9a26a6 100644 (file)
@@ -47,7 +47,7 @@ typedef enum {
   ETYPE_WINDOW,
   ETYPE_TOOLKIT,
   ETYPE_KEYBOARD,
-  
+  ETYPE_MOUSE,
   ETYPE_LAST_DEFINED
 } EventTypeCategory;
 
@@ -65,7 +65,6 @@ typedef struct {
   EventTypeCategory event_type_cat;
 } SpiListenerStruct;
 
-
 SpiListenerStruct *
 spi_listener_struct_new (Accessibility_EventListener listener, CORBA_Environment *ev)
 {
@@ -82,7 +81,6 @@ spi_listener_struct_free (SpiListenerStruct *ls, CORBA_Environment *ev)
   g_free (ls);
 }
 
-
 static void
 desktop_add_application (SpiDesktop *desktop,
                         guint index, gpointer data)
@@ -248,6 +246,10 @@ parse_event_type (EventTypeStruct *etype, const char *event_name)
     {
       etype->type_cat = ETYPE_FOCUS;
     }
+  else if (!g_ascii_strncasecmp (event_name, "mouse:", 6))
+    {
+      etype->type_cat = ETYPE_MOUSE;
+    }
   else if (!g_ascii_strncasecmp (event_name, "object:", 7))
     {
       etype->type_cat = ETYPE_OBJECT;
@@ -332,6 +334,7 @@ get_listener_list (SpiRegistry      *registry,
       case ETYPE_WINDOW:
        ret = &registry->window_listeners;
        break;
+      case ETYPE_MOUSE:
       case ETYPE_TOOLKIT:
        ret = &registry->toolkit_listeners;
        break;
@@ -670,7 +673,7 @@ spi_registry_init (SpiRegistry *registry)
                    G_CALLBACK (desktop_remove_application),
                    registry);
 
-  registry->de_controller = NULL;
+  registry->de_controller = spi_device_event_controller_new (registry);
 }
 
 BONOBO_TYPE_FUNC_FULL (SpiRegistry,
index d842433..eb665c7 100644 (file)
@@ -58,6 +58,10 @@ main (int argc, char **argv)
 
   SPI_registerGlobalEventListener (generic_listener,
                                   "focus:");
+  SPI_registerGlobalEventListener (specific_listener,
+                                  "mouse:rel");
+  SPI_registerGlobalEventListener (specific_listener,
+                                  "mouse:abs");
   SPI_registerGlobalEventListener (generic_listener,
                                   "object:property-change");
   SPI_registerGlobalEventListener (specific_listener,
@@ -207,7 +211,8 @@ void
 report_detail_event (const AccessibleEvent *event, void *user_data)
 {
   char *s = Accessible_getName (event->source);
-  fprintf (stderr, "(detail) %s %s\n", event->type, s);
+  fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
+          event->detail1, event->detail2);
   if (s) SPI_freeString (s);
 }