[mutter/wip/wayland-kms: 4/15] wayland: Add keyboard support
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/wayland-kms: 4/15] wayland: Add keyboard support
- Date: Wed, 18 Jul 2012 16:05:19 +0000 (UTC)
commit 310736818a244315df3000ed2700a3c9cdb1ea4f
Author: Neil Roberts <neil linux intel com>
Date: Tue Jan 17 19:54:26 2012 +0000
wayland: Add keyboard support
This adds basic keyboard support to the wayland compositor.
Auto-repeated key events are filtered out because the Wayland clients
are expected to generate them themselves. The wayland keyboard input
focus surface is updated whenever Mutter sees a FocusIn event so that
it will stay in synch with whatever surface Mutter wants as the focus.
src/core/display.c | 12 +++++
src/wayland/meta-wayland-input-device.c | 71 +++++++++++++++++++++++++++++++
src/wayland/meta-wayland-private.h | 16 ++++---
src/wayland/meta-wayland.c | 28 ++++++++++++
4 files changed, 121 insertions(+), 6 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index 0d18ed1..610c8c9 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -72,6 +72,9 @@
#include <X11/extensions/Xfixes.h>
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_WAYLAND
+#include "meta-wayland-private.h"
+#endif
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
(g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \
@@ -2167,6 +2170,15 @@ meta_display_handle_event (MetaDisplay *display,
}
break;
case FocusIn:
+#ifdef HAVE_WAYLAND
+ {
+ MetaWaylandCompositor *compositor =
+ meta_wayland_compositor_get_default ();
+ meta_wayland_compositor_set_input_focus (compositor,
+ window);
+ }
+#endif
+ /* fall through */
case FocusOut:
if (window)
{
diff --git a/src/wayland/meta-wayland-input-device.c b/src/wayland/meta-wayland-input-device.c
index 89dcd55..adba30c 100644
--- a/src/wayland/meta-wayland-input-device.c
+++ b/src/wayland/meta-wayland-input-device.c
@@ -25,6 +25,7 @@
#include <clutter/wayland/clutter-wayland-compositor.h>
#include <clutter/wayland/clutter-wayland-surface.h>
#include <stdlib.h>
+#include <string.h>
#include <linux/input.h>
#include "meta-wayland-input-device.h"
#include "meta-wayland-private.h"
@@ -160,6 +161,70 @@ handle_button_event (MetaWaylandInputDevice *input_device,
device->grab->interface->button (device->grab, event->time, button, state);
}
+static void
+handle_key_event (MetaWaylandInputDevice *input_device,
+ const ClutterKeyEvent *event)
+{
+ struct wl_input_device *device =
+ (struct wl_input_device *) input_device;
+ gboolean state = event->type == CLUTTER_KEY_PRESS;
+ guint evdev_code;
+
+ /* We can't do anything with the event if we can't get an evdev
+ keycode for it */
+ if (event->device == NULL ||
+ !clutter_input_device_keycode_to_evdev (event->device,
+ event->hardware_keycode,
+ &evdev_code))
+ return;
+
+ /* We want to ignore events that are sent because of auto-repeat. In
+ the Clutter event stream these appear as a single key press
+ event. We can detect that because the key will already have been
+ pressed */
+ if (state)
+ {
+ uint32_t *end = (void *) ((char *) device->keys.data + device->keys.size);
+ uint32_t *k;
+
+ /* Ignore the event if the key is already down */
+ for (k = device->keys.data; k < end; k++)
+ if (*k == evdev_code)
+ return;
+
+ /* Otherwise add the key to the list of pressed keys */
+ k = wl_array_add (&device->keys, sizeof (*k));
+ *k = evdev_code;
+ }
+ else
+ {
+ uint32_t *end = (void *) ((char *) device->keys.data + device->keys.size);
+ uint32_t *k;
+
+ /* Remove the key from the array */
+ for (k = device->keys.data; k < end; k++)
+ if (*k == evdev_code)
+ {
+ *k = *(end - 1);
+ device->keys.size -= sizeof (*k);
+
+ goto found;
+ }
+
+ g_warning ("unexpected key release event for key 0x%x", evdev_code);
+
+ found:
+ (void) 0;
+ }
+
+ if (device->keyboard_focus_resource)
+ wl_resource_post_event (device->keyboard_focus_resource,
+ WL_INPUT_DEVICE_KEY,
+ event->time,
+ evdev_code,
+ state);
+}
+
void
meta_wayland_input_device_handle_event (MetaWaylandInputDevice *input_device,
const ClutterEvent *event)
@@ -177,6 +242,12 @@ meta_wayland_input_device_handle_event (MetaWaylandInputDevice *input_device,
(const ClutterButtonEvent *) event);
break;
+ case CLUTTER_KEY_PRESS:
+ case CLUTTER_KEY_RELEASE:
+ handle_key_event (input_device,
+ (const ClutterKeyEvent *) event);
+ break;
+
default:
break;
}
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 0e4e2ec..b0896a6 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -28,6 +28,7 @@
#include "window-private.h"
#include "meta-wayland-input-device.h"
+#include "window-private.h"
typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
@@ -133,17 +134,20 @@ struct _MetaWaylandCompositor
guint32 implicit_grab_button;
};
-void meta_wayland_init (void);
-void meta_wayland_finalize (void);
+void meta_wayland_init (void);
+void meta_wayland_finalize (void);
/* We maintain a singleton MetaWaylandCompositor which can be got at via this
* API after meta_wayland_init() has been called. */
-MetaWaylandCompositor *meta_wayland_compositor_get_default (void);
+MetaWaylandCompositor *meta_wayland_compositor_get_default (void);
+
+void meta_wayland_handle_sig_child (void);
-void meta_wayland_handle_sig_child (void);
+MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid);
-MetaWaylandSurface *meta_wayland_lookup_surface_for_xid (guint32 xid);
+void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor);
-void meta_wayland_compositor_repick (MetaWaylandCompositor *compositor);
+void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
+ MetaWindow *window);
#endif /* META_WAYLAND_PRIVATE_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 38173d0..bf900aa 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -361,6 +361,34 @@ meta_wayland_compositor_repick (MetaWaylandCompositor *compositor)
NULL);
}
+void
+meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
+ MetaWindow *window)
+{
+ struct wl_surface *surface = NULL;
+
+ if (window)
+ {
+ MetaWindowActor *window_actor =
+ META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
+ ClutterActor *shaped_texture =
+ meta_window_actor_get_shaped_texture (window_actor);
+
+ if (CLUTTER_WAYLAND_IS_SURFACE (shaped_texture))
+ {
+ ClutterWaylandSurface *surface_actor =
+ CLUTTER_WAYLAND_SURFACE (shaped_texture);
+
+ surface = clutter_wayland_surface_get_surface (surface_actor);
+ }
+ }
+
+ wl_input_device_set_keyboard_focus ((struct wl_input_device *)
+ compositor->input_device,
+ (struct wl_surface *) surface,
+ get_time ());
+}
+
static void
surface_actor_destroyed_cb (void *user_data,
GObject *old_object)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]