compositor,shell: move debug key code to core
The code for the key binding that triggers debug key bindings, that is,
the code that makes mod+SHIFT+SPACE work, used to live in shell.c. I
want to make the debug key bindings available in ivi-shell too, so this
code should be shared. Move it to core.
The code was originally introduced in
commit c509d2b1523364d38da3038eec7b46cd71acd3f5
so update the copyright in binding.c to reflect that.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Acked-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
Reviewed-by: Daniel Stone <daniels@collabora.com>
diff --git a/src/bindings.c b/src/bindings.c
index 8d4c133..6aeed91 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Intel Corporation
+ * Copyright © 2011-2012 Intel Corporation
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
@@ -23,6 +23,7 @@
#include "config.h"
#include <stdlib.h>
+#include <linux/input.h>
#include "compositor.h"
@@ -421,3 +422,147 @@
return count;
}
+
+struct debug_binding_grab {
+ struct weston_keyboard_grab grab;
+ struct weston_seat *seat;
+ uint32_t key[2];
+ int key_released[2];
+};
+
+static void
+debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
+ uint32_t key, uint32_t state)
+{
+ struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
+ struct weston_compositor *ec = db->seat->compositor;
+ struct wl_display *display = ec->wl_display;
+ struct wl_resource *resource;
+ uint32_t serial;
+ int send = 0, terminate = 0;
+ int check_binding = 1;
+ int i;
+ struct wl_list *resource_list;
+
+ if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
+ /* Do not run bindings on key releases */
+ check_binding = 0;
+
+ for (i = 0; i < 2; i++)
+ if (key == db->key[i])
+ db->key_released[i] = 1;
+
+ if (db->key_released[0] && db->key_released[1]) {
+ /* All key releases been swalled so end the grab */
+ terminate = 1;
+ } else if (key != db->key[0] && key != db->key[1]) {
+ /* Should not swallow release of other keys */
+ send = 1;
+ }
+ } else if (key == db->key[0] && !db->key_released[0]) {
+ /* Do not check bindings for the first press of the binding
+ * key. This allows it to be used as a debug shortcut.
+ * We still need to swallow this event. */
+ check_binding = 0;
+ } else if (db->key[1]) {
+ /* If we already ran a binding don't process another one since
+ * we can't keep track of all the binding keys that were
+ * pressed in order to swallow the release events. */
+ send = 1;
+ check_binding = 0;
+ }
+
+ if (check_binding) {
+ if (weston_compositor_run_debug_binding(ec, db->seat, time,
+ key, state)) {
+ /* We ran a binding so swallow the press and keep the
+ * grab to swallow the released too. */
+ send = 0;
+ terminate = 0;
+ db->key[1] = key;
+ } else {
+ /* Terminate the grab since the key pressed is not a
+ * debug binding key. */
+ send = 1;
+ terminate = 1;
+ }
+ }
+
+ if (send) {
+ serial = wl_display_next_serial(display);
+ resource_list = &grab->keyboard->focus_resource_list;
+ wl_resource_for_each(resource, resource_list) {
+ wl_keyboard_send_key(resource, serial, time, key, state);
+ }
+ }
+
+ if (terminate) {
+ weston_keyboard_end_grab(grab->keyboard);
+ if (grab->keyboard->input_method_resource)
+ grab->keyboard->grab = &grab->keyboard->input_method_grab;
+ free(db);
+ }
+}
+
+static void
+debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
+ uint32_t mods_depressed, uint32_t mods_latched,
+ uint32_t mods_locked, uint32_t group)
+{
+ struct wl_resource *resource;
+ struct wl_list *resource_list;
+
+ resource_list = &grab->keyboard->focus_resource_list;
+
+ wl_resource_for_each(resource, resource_list) {
+ wl_keyboard_send_modifiers(resource, serial, mods_depressed,
+ mods_latched, mods_locked, group);
+ }
+}
+
+static void
+debug_binding_cancel(struct weston_keyboard_grab *grab)
+{
+ struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
+
+ weston_keyboard_end_grab(grab->keyboard);
+ free(db);
+}
+
+struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
+ debug_binding_key,
+ debug_binding_modifiers,
+ debug_binding_cancel,
+};
+
+static void
+debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
+{
+ struct debug_binding_grab *grab;
+
+ grab = calloc(1, sizeof *grab);
+ if (!grab)
+ return;
+
+ grab->seat = seat;
+ grab->key[0] = key;
+ grab->grab.interface = &debug_binding_keyboard_grab;
+ weston_keyboard_start_grab(seat->keyboard, &grab->grab);
+}
+
+/** Install the trigger binding for debug bindings.
+ *
+ * \param compositor The compositor.
+ * \param mod The modifier.
+ *
+ * This will add a key binding for modifier+SHIFT+SPACE that will trigger
+ * debug key bindings.
+ */
+WL_EXPORT void
+weston_install_debug_key_binding(struct weston_compositor *compositor,
+ uint32_t mod)
+{
+ weston_compositor_add_key_binding(compositor, KEY_SPACE,
+ mod | MODIFIER_SHIFT,
+ debug_binding, NULL);
+}