From 67fbfebd6d923bdd476bc988c8d32038dd47314b Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Tue, 10 Jun 2008 10:57:50 +0000 Subject: [PATCH] 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 --- ChangeLog | 16 +++++++++-- clutter/osx/clutter-event-osx.c | 3 +- clutter/x11/clutter-event-x11.c | 22 ++++++++++++-- tests/test-events.c | 51 ++++++++++++++++++++++++++------- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c30fcee1..3e6be97c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,21 @@ +2008-06-10 Chris Lord + + 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 * 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 diff --git a/clutter/osx/clutter-event-osx.c b/clutter/osx/clutter-event-osx.c index 2e5f5c3f3..a622cc4dc 100644 --- a/clutter/osx/clutter-event-osx.c +++ b/clutter/osx/clutter-event-osx.c @@ -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], diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 0315dbc70..fcfdfca46 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -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 diff --git a/tests/test-events.c b/tests/test-events.c index 9bf5af489..6e53e4ab1 100644 --- a/tests/test-events.c +++ b/tests/test-events.c @@ -1,4 +1,5 @@ #include +#include 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 (s, S, 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, ""); + if (event->modifier_state & CLUTTER_LOCK_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_CONTROL_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_MOD1_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_MOD2_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_MOD3_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_MOD4_MASK) + strcat (keybuf, ""); + if (event->modifier_state & CLUTTER_MOD5_MASK) + strcat (keybuf, ""); + 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);