Bug #916 - ClutterKeyEvent:unicode_value is ignored
authorChris Lord <chris@openedhand.com>
Tue, 10 Jun 2008 10:57:50 +0000 (10:57 +0000)
committerChris Lord <chris@openedhand.com>
Tue, 10 Jun 2008 10:57:50 +0000 (10:57 +0000)
        Bug #950 - AltGr not handled

        * clutter/osx/clutter-event-osx.c: (clutter_event_osx_translate):
        * clutter/x11/clutter-event-x11.c: (translate_key_event):
        * tests/test-events.c: (fill_keybuf), (input_cb):
        Apply patch from Tommi Komulainen, fill the unicode_value attribute of
        the ClutterKeyEvent struct. Also use XKeycodeToKeysym, as suggested in
        bug #950, comment #2

ChangeLog
clutter/osx/clutter-event-osx.c
clutter/x11/clutter-event-x11.c
tests/test-events.c

index 3c30fce..3e6be97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,21 @@
+2008-06-10  Chris Lord  <chris@openedhand.com>
+
+       Bug #916 - ClutterKeyEvent:unicode_value is ignored
+       Bug #950 - AltGr not handled
+
+       * clutter/osx/clutter-event-osx.c: (clutter_event_osx_translate):
+       * clutter/x11/clutter-event-x11.c: (translate_key_event):
+       * tests/test-events.c: (fill_keybuf), (input_cb):
+       Apply patch from Tommi Komulainen, fill the unicode_value attribute of
+       the ClutterKeyEvent struct. Also use XKeycodeToKeysym, as suggested in
+       bug #950, comment #2
+
 2008-06-10  Matthew Allum  <mallum@openedhand.com>
 
        * clutter/clutter-texture.c:
-        Minor reformatting cleanups. Emit filter-quality prop on change.
+       Minor reformatting cleanups. Emit filter-quality prop on change.
        * clutter/glx/clutter-glx-texture-pixmap.c:
-        Support mipmaps via filter quality prop.
+       Support mipmaps via filter quality prop.
 
 2008-06-10  Chris Lord  <chris@openedhand.com>
 
index 2e5f5c3..a622cc4 100644 (file)
@@ -107,7 +107,7 @@ static GPollFunc old_poll_func = NULL;
    * For now handle some common/simple keys only. Might not work with other
    * hardware than mine (MacBook Pro, finnish layout). Sorry.
    */
-  unichar c = [[self characters] characterAtIndex:0];
+  unichar c = [[self charactersIgnoringModifiers] characterAtIndex:0];
 
   /* Latin-1 characters, 1:1 mapping - this ought to be reliable */
   if ((c >= 0x0020 && c <= 0x007e) ||
@@ -224,6 +224,7 @@ clutter_event_osx_translate (NSEvent *nsevent, ClutterEvent *event)
       event->key.hardware_keycode = [nsevent keyCode];
       event->key.modifier_state = [nsevent clutterModifierState];
       event->key.keyval = [nsevent clutterKeyVal];
+      event->key.unicode_value = [[nsevent characters] characterAtIndex:0];
 
       CLUTTER_NOTE (EVENT, "key %d (%s) (%s) %s, keyval %d",
                     [nsevent keyCode],
index 0315dbc..fcfdfca 100644 (file)
@@ -220,6 +220,9 @@ translate_key_event (ClutterBackend *backend,
                      ClutterEvent   *event,
                      XEvent         *xevent)
 {
+  char buffer[6];
+  int n;
+  
   CLUTTER_NOTE (EVENT, "Translating key %s event",
                 xevent->xany.type == KeyPress ? "press" : "release");
 
@@ -229,12 +232,25 @@ translate_key_event (ClutterBackend *backend,
   event->key.modifier_state = (ClutterModifierType) xevent->xkey.state;
   event->key.hardware_keycode = xevent->xkey.keycode;
 
-  /* FIXME: We need to handle other modifiers rather than just shift */
+  /* keyval is the key ignoring all modifiers ('1' vs. '!') */
   event->key.keyval =
     XKeycodeToKeysym (xevent->xkey.display,
                       xevent->xkey.keycode,
-                      (event->key.modifier_state & CLUTTER_SHIFT_MASK) ? 1
-                                                                       : 0);
+                      0);
+
+  /* unicode_value is the printable representation */
+  n = XLookupString (&xevent->xkey, buffer, sizeof (buffer), NULL, NULL);
+  if (n == NoSymbol)
+    {
+      event->key.unicode_value = (gunichar)'\0';
+    }
+  else
+    {
+      event->key.unicode_value = g_utf8_get_char_validated (buffer, n);
+      if ((event->key.unicode_value == -1) ||
+          (event->key.unicode_value == -1))
+        event->key.unicode_value = (gunichar)'\0';
+    }
 }
 
 static gboolean
index 9bf5af4..6e53e4a 100644 (file)
@@ -1,4 +1,5 @@
 #include <clutter/clutter.h>
+#include <string.h>
 
 gboolean IsFullScreen = FALSE, IsMotion = TRUE;
 
@@ -84,28 +85,58 @@ key_focus_in_cb (ClutterActor    *actor,
     }
 }
 
+static void
+fill_keybuf (char *keybuf, ClutterKeyEvent *event)
+{
+  char utf8[6];
+  int len;
+
+  /* printable character, if any (ß, ∑) */
+  len = g_unichar_to_utf8 (event->unicode_value, utf8);
+  utf8[len] = '\0';
+  sprintf(keybuf, "'%s' ", utf8);
+
+  /* key combination (<Mod1>s, <Shift><Mod1>S, <Ctrl><Mod1>Delete) */
+  len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->keyval),
+                           utf8);
+  utf8[len] = '\0';
+
+  if (event->modifier_state & CLUTTER_SHIFT_MASK)
+    strcat (keybuf, "<Shift>");
+  if (event->modifier_state & CLUTTER_LOCK_MASK)
+    strcat (keybuf, "<Lock>");
+  if (event->modifier_state & CLUTTER_CONTROL_MASK)
+    strcat (keybuf, "<Control>");
+  if (event->modifier_state & CLUTTER_MOD1_MASK)
+    strcat (keybuf, "<Mod1>");
+  if (event->modifier_state & CLUTTER_MOD2_MASK)
+    strcat (keybuf, "<Mod2>");
+  if (event->modifier_state & CLUTTER_MOD3_MASK)
+    strcat (keybuf, "<Mod3>");
+  if (event->modifier_state & CLUTTER_MOD4_MASK)
+    strcat (keybuf, "<Mod4>");
+  if (event->modifier_state & CLUTTER_MOD5_MASK)
+    strcat (keybuf, "<Mod5>");
+  strcat (keybuf, utf8);
+}
+
 static gboolean
 input_cb (ClutterActor    *actor,
          ClutterEvent    *event,
          gpointer         data)
 {
   ClutterStage *stage = CLUTTER_STAGE (clutter_stage_get_default ());
-  gchar keybuf[9], *source = (gchar*)data;
-  int   len = 0;
+  gchar keybuf[128], *source = (gchar*)data;
 
   switch (event->type)
     {
     case CLUTTER_KEY_PRESS:
-      len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
-                              keybuf);
-      keybuf[len] = '\0';
-      g_print ("[%s] KEY PRESS '%s'", source, keybuf);
+      fill_keybuf (keybuf, &event->key);
+      printf ("[%s] KEY PRESS %s", source, keybuf);
       break;
     case CLUTTER_KEY_RELEASE:
-      len = g_unichar_to_utf8 (clutter_keysym_to_unicode (event->key.keyval),
-                              keybuf);
-      keybuf[len] = '\0';
-      g_print ("[%s] KEY RELEASE '%s'", source, keybuf);
+      fill_keybuf (keybuf, &event->key);
+      printf ("[%s] KEY RELEASE %s", source, keybuf);
       break;
     case CLUTTER_MOTION:
       g_print ("[%s] MOTION", source);