[clutter/fosdem-2012] test-wayland-surface: Add keyboard support



commit 9912bf73abfdc7462034d7e0405f2e799a43a763
Author: Neil Roberts <neil linux intel com>
Date:   Tue Jan 17 18:39:13 2012 +0000

    test-wayland-surface: Add keyboard support
    
    This adds basic keyboard support to the demo wayland compositor.
    Auto-repeated key events are filtered out because the Wayland clients
    are expected to generate them themselves. The compositor implements
    click-to-focus.

 tests/interactive/test-wayland-surface.c |   15 ++++++
 tests/interactive/tws-input.c            |   71 ++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)
---
diff --git a/tests/interactive/test-wayland-surface.c b/tests/interactive/test-wayland-surface.c
index 5bf3016..980d2b1 100644
--- a/tests/interactive/test-wayland-surface.c
+++ b/tests/interactive/test-wayland-surface.c
@@ -1061,6 +1061,21 @@ event_cb (ClutterActor *stage,
 {
   tws_input_device_handle_event (compositor->input_device, event);
 
+  /* This implements click-to-focus */
+  if (event->type == CLUTTER_BUTTON_PRESS &&
+      CLUTTER_WAYLAND_IS_SURFACE (event->any.source))
+    {
+      ClutterWaylandSurface *cw_surface =
+        CLUTTER_WAYLAND_SURFACE (event->any.source);
+      struct wl_surface *wl_surface =
+        clutter_wayland_surface_get_surface (cw_surface);
+
+      wl_input_device_set_keyboard_focus ((struct wl_input_device *)
+                                          compositor->input_device,
+                                          wl_surface,
+                                          event->any.time);
+    }
+
   return FALSE;
 }
 
diff --git a/tests/interactive/tws-input.c b/tests/interactive/tws-input.c
index 0dbe60b..8c0f600 100644
--- a/tests/interactive/tws-input.c
+++ b/tests/interactive/tws-input.c
@@ -7,6 +7,7 @@
 #include <clutter/wayland/clutter-wayland-surface.h>
 #include <linux/input.h>
 #include <stdlib.h>
+#include <string.h>
 #include "tws-input.h"
 #include "tws-compositor.h"
 
@@ -139,6 +140,70 @@ handle_button_event (TwsInputDevice *input_device,
   device->grab->interface->button (device->grab, event->time, button, state);
 }
 
+static void
+handle_key_event (TwsInputDevice *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
 tws_input_device_handle_event (TwsInputDevice *input_device,
                                const ClutterEvent *event)
@@ -156,6 +221,12 @@ tws_input_device_handle_event (TwsInputDevice *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;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]