x11: Store the group inside the event platform data
authorEmmanuele Bassi <ebassi@linux.intel.com>
Thu, 8 Jul 2010 14:47:18 +0000 (15:47 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 13 Jul 2010 07:27:48 +0000 (08:27 +0100)
Now that we have private, per-event platform data, we can start putting
it to good use. The first, most simple use is to store the key group
given the event's modifiers. Since we assume a modern X11, we use XKB
to retrieve it, or we simply fall back to 0 by default.

The data is exposed as a ClutterX11-specific function, within the
sanctioned clutter_x11_* namespace.

clutter/x11/clutter-backend-x11.c
clutter/x11/clutter-backend-x11.h
clutter/x11/clutter-event-x11.c
clutter/x11/clutter-x11.h

index 81ce4d8..8bc13ec 100644 (file)
@@ -475,6 +475,29 @@ clutter_backend_x11_get_features (ClutterBackend *backend)
   return CLUTTER_FEATURE_STAGE_USER_RESIZE | CLUTTER_FEATURE_STAGE_CURSOR;
 }
 
+static void
+clutter_backend_x11_copy_event_data (ClutterBackend *backend,
+                                     ClutterEvent   *src,
+                                     ClutterEvent   *dest)
+{
+  gpointer event_x11;
+
+  event_x11 = _clutter_event_get_platform_data (src);
+  if (event_x11 != NULL)
+    _clutter_event_set_platform_data (dest, _clutter_event_x11_copy (event_x11));
+}
+
+static void
+clutter_backend_x11_free_event_data (ClutterBackend *backend,
+                                     ClutterEvent   *event)
+{
+  gpointer event_x11;
+
+  event_x11 = _clutter_event_get_platform_data (event);
+  if (event_x11 != NULL)
+    _clutter_event_x11_free (event_x11);
+}
+
 gboolean
 clutter_backend_x11_handle_event (ClutterBackendX11 *backend_x11,
                                   XEvent *xevent)
@@ -516,6 +539,8 @@ clutter_backend_x11_class_init (ClutterBackendX11Class *klass)
   backend_class->add_options = clutter_backend_x11_add_options;
   backend_class->get_features = clutter_backend_x11_get_features;
   backend_class->get_device_manager = clutter_backend_x11_get_device_manager;
+  backend_class->copy_event_data = clutter_backend_x11_copy_event_data;
+  backend_class->free_event_data = clutter_backend_x11_free_event_data;
 
   backendx11_class->handle_event = clutter_backend_x11_handle_event;
 }
index eebdc4d..4826343 100644 (file)
@@ -109,6 +109,9 @@ struct _ClutterBackendX11Class
                             XEvent            *xevent);
 };
 
+/* platform-specific event data */
+typedef struct _ClutterEventX11 ClutterEventX11;
+
 void   _clutter_backend_x11_events_init (ClutterBackend *backend);
 void   _clutter_backend_x11_events_uninit (ClutterBackend *backend);
 
@@ -146,6 +149,15 @@ _clutter_x11_get_device_for_xid (XID id);
 void
 _clutter_x11_select_events (Window xwin);
 
+ClutterEventX11 *
+_clutter_event_x11_new (void);
+
+ClutterEventX11 *
+_clutter_event_x11_copy (ClutterEventX11 *event_x11);
+
+void
+_clutter_event_x11_free (ClutterEventX11 *event_x11);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_BACKEND_X11_H__ */
index 28bb4b3..9643f18 100644 (file)
 #include <X11/extensions/XInput.h>
 #endif
 
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
 /* XEMBED protocol support for toolkit embedding */
 #define XEMBED_MAPPED                   (1 << 0)
 #define MAX_SUPPORTED_XEMBED_VERSION    1
@@ -85,6 +89,34 @@ struct _ClutterEventSource
   GPollFD event_poll_fd;
 };
 
+struct _ClutterEventX11
+{
+  /* additional fields for Key events */
+  gint key_group;
+};
+
+ClutterEventX11 *
+_clutter_event_x11_new (void)
+{
+  return g_slice_new0 (ClutterEventX11);
+}
+
+ClutterEventX11 *
+_clutter_event_x11_copy (ClutterEventX11 *event_x11)
+{
+  if (event_x11 != NULL)
+    return g_slice_dup (ClutterEventX11, event_x11);
+
+  return NULL;
+}
+
+void
+_clutter_event_x11_free (ClutterEventX11 *event_x11)
+{
+  if (event_x11 != NULL)
+    g_slice_free (ClutterEventX11, event_x11);
+}
+
 static gboolean clutter_event_prepare  (GSource     *source,
                                         gint        *timeout);
 static gboolean clutter_event_check    (GSource     *source);
@@ -300,12 +332,30 @@ translate_key_event (ClutterBackend   *backend,
                      ClutterEvent     *event,
                      XEvent           *xevent)
 {
-  char buffer[256+1];
+  ClutterEventX11 *event_x11;
+  char buffer[256 + 1];
   int n;
   
   CLUTTER_NOTE (EVENT, "Translating key %s event",
                 xevent->xany.type == KeyPress ? "press" : "release");
 
+  /* KeyEvents have platform specific data associated to them */
+  event_x11 = _clutter_event_x11_new ();
+  _clutter_event_set_platform_data (event, event_x11);
+
+#ifdef HAVE_XKB
+  event_x11->key_group = XkbGroupForCoreState (xevent->xkey.state);
+
+  CLUTTER_NOTE (EVENT, "Key group: %d (xkb enabled: yes)",
+                event_x11->key_group);
+#else
+  /* we force the key group to 0 */
+  event_x11->key_group = 0;
+
+  CLUTTER_NOTE (EVENT, "Key group: %d (xkb enabled: no)",
+                event_x11->key_group);
+#endif /* HAVE_XKB */
+
   event->key.time = xevent->xkey.time;
   event->key.modifier_state = (ClutterModifierType) xevent->xkey.state;
   event->key.hardware_keycode = xevent->xkey.keycode;
@@ -326,8 +376,8 @@ translate_key_event (ClutterBackend   *backend,
           (event->key.unicode_value != -2))
         return;
     }
-  
-  event->key.unicode_value = (gunichar)'\0';
+  else
+    event->key.unicode_value = (gunichar)'\0';
 }
 
 static gboolean
@@ -509,7 +559,9 @@ event_translate (ClutterBackend *backend,
           if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) ||
               (stage_x11->xwin_width != xevent->xconfigure.width) ||
               (stage_x11->xwin_height != xevent->xconfigure.height))
-          clutter_actor_queue_relayout (CLUTTER_ACTOR (stage));
+            {
+              clutter_actor_queue_relayout (CLUTTER_ACTOR (stage));
+            }
 
           /* If we're fullscreened, we want these variables to
            * represent the size of the window before it was set
@@ -1031,9 +1083,7 @@ events_queue (ClutterBackend *backend)
          g_queue_push_head (clutter_context->events_queue, event);
         }
       else
-        {
-          clutter_event_free (event);
-        }
+        clutter_event_free (event);
     }
 }
 
@@ -1209,3 +1259,29 @@ clutter_x11_get_current_event_time (void)
 
   return CLUTTER_BACKEND_X11 (backend)->last_event_time;
 }
+
+/**
+ * clutter_x11_event_get_key_group:
+ * @event: a #ClutterEvent of type %CLUTTER_KEY_PRESS or %CLUTTER_KEY_RELEASE
+ *
+ * Retrieves the group for the modifiers set in @event
+ *
+ * Return value: the group id
+ *
+ * Since: 1.4
+ */
+gint
+clutter_x11_event_get_key_group (const ClutterEvent *event)
+{
+  ClutterEventX11 *event_x11;
+
+  g_return_val_if_fail (event != NULL, 0);
+  g_return_val_if_fail (event->type == CLUTTER_KEY_PRESS ||
+                        event->type == CLUTTER_KEY_RELEASE, 0);
+
+  event_x11 = _clutter_event_get_platform_data (event);
+  if (event_x11 == NULL)
+    return 0;
+
+  return event_x11->key_group;
+}
index 630e63a..70e3324 100644 (file)
@@ -141,6 +141,8 @@ gboolean clutter_x11_get_use_argb_visual (void);
 
 Time clutter_x11_get_current_event_time (void);
 
+gint clutter_x11_event_get_key_group (const ClutterEvent *event);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_X11_H__ */