2008-02-25 Li Yuan <li.yuan@sun.com>
[platform/core/uifw/at-spi2-atk.git] / registryd / deviceeventcontroller.c
index 7e4e2e6..b80184a 100644 (file)
@@ -82,8 +82,9 @@ static unsigned int key_modifier_mask =
 static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset */
 
 static GQuark spi_dec_private_quark = 0;
+static XModifierKeymap* xmkeymap = NULL;
 
-int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
+static int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
 
 typedef enum {
   SPI_DEVICE_TYPE_KBD,
@@ -458,6 +459,8 @@ spi_dec_button_update_and_emit (SpiDEController *controller,
          }
        else
          spi_dec_set_unlatch_pending (controller, mask_return);
+
+        CORBA_free (e.any_data._value);
       }
       return TRUE;
     }
@@ -473,6 +476,7 @@ spi_dec_mouse_check (SpiDEController *controller,
                     int *x, int *y, gboolean *moved)
 {
   Accessibility_Event e;
+  Accessibility_EventDetails *details;
   CORBA_Environment ev;
   int win_x_return,win_y_return;
   unsigned int mask_return;
@@ -510,6 +514,8 @@ spi_dec_mouse_check (SpiDEController *controller,
       Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
                                          &e,
                                          &ev);
+      details = e.any_data._value;
+      CORBA_free (details);
       e.type = "mouse:rel";  
       e.source = BONOBO_OBJREF (controller->registry->desktop);
       e.detail1 = *x - last_mouse_pos->x;
@@ -524,6 +530,8 @@ spi_dec_mouse_check (SpiDEController *controller,
       Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
                                          &e,
                                          &ev);
+      details = e.any_data._value;
+      CORBA_free (details);
       *moved = True;
     }
   else
@@ -564,6 +572,7 @@ spi_dec_emit_modifier_event (SpiDEController *controller, guint prev_mask,
   Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
                                      &e,
                                      &ev);
+  CORBA_free (e.any_data._value);
 }
 
 static gboolean
@@ -1083,6 +1092,7 @@ spi_device_event_controller_forward_mouse_event (SpiDEController *controller,
       Accessibility_Registry_notifyEvent (BONOBO_OBJREF (controller->registry),
                                          &e,
                                          &ev);
+      CORBA_free (e.any_data._value);
     }
 
   xkb_mod_unlatch_occurred = (xevent->type == ButtonPress ||
@@ -1110,6 +1120,9 @@ global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
   priv = (DEControllerPrivateData *)
          g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);  
 
+  if (xevent->type == MappingNotify)
+    xmkeymap = NULL;
+
   if (xevent->type == KeyPress || xevent->type == KeyRelease)
     {
       if (controller->xevie_display == NULL)
@@ -1227,7 +1240,7 @@ global_filter_fn (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
   return GDK_FILTER_CONTINUE;
 }
 
-int
+static int
 _spi_controller_device_error_handler (Display *display, XErrorEvent *error)
 {
   if (error->error_code == BadAccess) 
@@ -1411,7 +1424,7 @@ spi_key_event_matches_listener (const Accessibility_DeviceEvent *key_event,
                                DEControllerKeyListener         *listener,
                                CORBA_boolean                    is_system_global)
 {
-  if ((key_event->modifiers == (CORBA_unsigned_short) (listener->mask & 0xFF)) &&
+  if (((key_event->modifiers & 0xFF) == (CORBA_unsigned_short) (listener->mask & 0xFF)) &&
        spi_key_set_contains_key (listener->keys, key_event) &&
        spi_eventtype_seq_contains_event (listener->listener.typeseq, key_event) && 
       (is_system_global == listener->mode->global))
@@ -1668,7 +1681,7 @@ spi_controller_update_key_grabs (SpiDEController           *controller,
 {
   GList *l, *next;
   gboolean   update_failed = FALSE;
-  KeyCode keycode;
+  KeyCode keycode = 0;
   
   g_return_val_if_fail (controller != NULL, FALSE);
 
@@ -2121,15 +2134,37 @@ dec_get_modifier_state (SpiDEController *controller)
 static gboolean
 dec_lock_modifiers (SpiDEController *controller, unsigned modifiers)
 {
-       return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
-                         modifiers, modifiers);
+    DEControllerPrivateData *priv = (DEControllerPrivateData *) 
+    g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);  
+    
+    if (priv->have_xkb) {
+        return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
+                                  modifiers, modifiers);
+    } else {
+       int mod_index;
+       for (mod_index=0;mod_index<8;mod_index++)
+           if (modifiers & (1<<mod_index))
+               dec_synth_keycode_press(controller, xmkeymap->modifiermap[mod_index]);
+       return TRUE;
+    }
 }
 
 static gboolean
 dec_unlock_modifiers (SpiDEController *controller, unsigned modifiers)
 {
-       return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
-                         modifiers, 0);
+    DEControllerPrivateData *priv = (DEControllerPrivateData *) 
+    g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);  
+    
+    if (priv->have_xkb) {
+        return XkbLockModifiers (spi_get_display (), XkbUseCoreKbd, 
+                                  modifiers, 0);
+    } else {
+       int mod_index;
+       for (mod_index=0;mod_index<8;mod_index++)
+           if (modifiers & (1<<mod_index))
+               dec_synth_keycode_release(controller, xmkeymap->modifiermap[mod_index]);
+       return TRUE;
+    }
 }
 
 static KeySym
@@ -2259,6 +2294,13 @@ impl_generate_keyboard_event (PortableServer_Servant           servant,
   
   gdk_error_trap_push ();
 
+  DEControllerPrivateData *priv = (DEControllerPrivateData *) 
+      g_object_get_qdata (G_OBJECT (controller), spi_dec_private_quark);
+
+  if (!priv->have_xkb && xmkeymap==NULL) {
+    xmkeymap = XGetModifierMapping(spi_get_display ());
+  }
+
   switch (synth_type)
     {
       case Accessibility_KEY_PRESS:
@@ -2426,15 +2468,12 @@ spi_device_event_controller_class_init (SpiDEControllerClass *klass)
 }
 
 #ifdef HAVE_XEVIE
-Bool isEvent(dpy,event,arg)
-     Display *dpy;
-     XEvent *event;
-     char *arg;
+static Bool isEvent(Display *dpy, XEvent *event, char *arg)
 {
    return TRUE;
 }
 
-gboolean
+static gboolean
 handle_io (GIOChannel *source,
            GIOCondition condition,
            gpointer data) 
@@ -2509,6 +2548,7 @@ spi_device_event_controller_forward_key_event (SpiDEController *controller,
 {
   CORBA_Environment ev;
   Accessibility_DeviceEvent key_event;
+  gboolean ret;
 
   g_assert (event->type == KeyPress || event->type == KeyRelease);
 
@@ -2520,7 +2560,9 @@ spi_device_event_controller_forward_key_event (SpiDEController *controller,
     spi_controller_update_key_grabs (controller, &key_event);
 
   /* relay to listeners, and decide whether to consume it or not */
-  return spi_controller_notify_keylisteners (controller, &key_event, CORBA_TRUE, &ev);
+  ret = spi_controller_notify_keylisteners (controller, &key_event, CORBA_TRUE, &ev);
+  CORBA_free(key_event.event_string);
+  return ret;
 }
 
 SpiDEController *