From d345a61e6c017af594a4d9624a861035be4dd592 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 8 Jul 2010 15:47:18 +0100 Subject: [PATCH] x11: Store the group inside the event platform data 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 | 25 +++++++++ clutter/x11/clutter-backend-x11.h | 12 +++++ clutter/x11/clutter-event-x11.c | 90 ++++++++++++++++++++++++++++--- clutter/x11/clutter-x11.h | 2 + 4 files changed, 122 insertions(+), 7 deletions(-) diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c index 81ce4d817..8bc13ec49 100644 --- a/clutter/x11/clutter-backend-x11.c +++ b/clutter/x11/clutter-backend-x11.c @@ -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; } diff --git a/clutter/x11/clutter-backend-x11.h b/clutter/x11/clutter-backend-x11.h index eebdc4db9..482634314 100644 --- a/clutter/x11/clutter-backend-x11.h +++ b/clutter/x11/clutter-backend-x11.h @@ -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__ */ diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index 28bb4b3ab..9643f189a 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -54,6 +54,10 @@ #include #endif +#ifdef HAVE_XKB +#include +#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; +} diff --git a/clutter/x11/clutter-x11.h b/clutter/x11/clutter-x11.h index 630e63af4..70e3324bb 100644 --- a/clutter/x11/clutter-x11.h +++ b/clutter/x11/clutter-x11.h @@ -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__ */