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.
This commit is contained in:
Emmanuele Bassi 2010-07-08 15:47:18 +01:00
parent f44ccba42e
commit d345a61e6c
4 changed files with 122 additions and 7 deletions

View 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;
}

View 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__ */

View File

@ -54,6 +54,10 @@
#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,7 +376,7 @@ translate_key_event (ClutterBackend *backend,
(event->key.unicode_value != -2))
return;
}
else
event->key.unicode_value = (gunichar)'\0';
}
@ -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));
}
/* If we're fullscreened, we want these variables to
* represent the size of the window before it was set
@ -1031,10 +1083,8 @@ events_queue (ClutterBackend *backend)
g_queue_push_head (clutter_context->events_queue, event);
}
else
{
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;
}

View 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__ */