[PATCH weston 1/3] compositor: Add debug key bindings infrastructure

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Thu Nov 8 07:20:45 PST 2012


Add the concept of debug key bindings, that are bindings that activate
debug features in the compositor. The bindings are added to a list in
the compositor, but the triggering them is left to the shell.

On the shell side, a global debug key binding is added. When the user
presses mod-shift-space, the shell will invoke the debug bindings based
on the next key press.

This also converts the debug shortcuts for repaint debugging, fan
repaint debugging and the hide overlays shortcut in compositor-drm to
use the new infrastructure.
---
 src/compositor-drm.c |    5 +-
 src/compositor.c     |    2 +
 src/compositor.h     |   11 +++++
 src/shell.c          |  128 ++++++++++++++++++++++++++++++++++++++++++++++++--
 src/util.c           |   38 +++++++++++++++
 5 files changed, 177 insertions(+), 7 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index f360568..8657b6b 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -2338,9 +2338,8 @@ drm_compositor_create(struct wl_display *display,
 
 	udev_device_unref(drm_device);
 
-	weston_compositor_add_key_binding(&ec->base, KEY_O,
-					  MODIFIER_CTRL | MODIFIER_ALT,
-					  hide_sprites_binding, ec);
+	weston_compositor_add_debug_binding(&ec->base, KEY_O,
+					    hide_sprites_binding, ec);
 
 	return &ec->base;
 
diff --git a/src/compositor.c b/src/compositor.c
index 2d5b263..7e88f16 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2819,6 +2819,7 @@ weston_compositor_init(struct weston_compositor *ec,
 	wl_list_init(&ec->key_binding_list);
 	wl_list_init(&ec->button_binding_list);
 	wl_list_init(&ec->axis_binding_list);
+	wl_list_init(&ec->debug_binding_list);
 	wl_list_init(&ec->fade.animation.link);
 
 	weston_plane_init(&ec->primary_plane, 0, 0);
@@ -2868,6 +2869,7 @@ weston_compositor_shutdown(struct weston_compositor *ec)
 	weston_binding_list_destroy_all(&ec->key_binding_list);
 	weston_binding_list_destroy_all(&ec->button_binding_list);
 	weston_binding_list_destroy_all(&ec->axis_binding_list);
+	weston_binding_list_destroy_all(&ec->debug_binding_list);
 
 	weston_plane_release(&ec->primary_plane);
 
diff --git a/src/compositor.h b/src/compositor.h
index 121f6bf..9bd2b08 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -320,6 +320,7 @@ struct weston_compositor {
 	struct wl_list key_binding_list;
 	struct wl_list button_binding_list;
 	struct wl_list axis_binding_list;
+	struct wl_list debug_binding_list;
 	struct {
 		struct weston_spring spring;
 		struct weston_animation animation;
@@ -631,6 +632,11 @@ weston_compositor_add_axis_binding(struct weston_compositor *compositor,
 			           enum weston_keyboard_modifier modifier,
 			           weston_axis_binding_handler_t binding,
 				   void *data);
+struct weston_binding *
+weston_compositor_add_debug_binding(struct weston_compositor *compositor,
+				    uint32_t key,
+				    weston_key_binding_handler_t binding,
+				    void *data);
 void
 weston_binding_destroy(struct weston_binding *binding);
 
@@ -651,6 +657,11 @@ void
 weston_compositor_run_axis_binding(struct weston_compositor *compositor,
 				   struct weston_seat *seat, uint32_t time,
 				   uint32_t axis, int32_t value);
+int
+weston_compositor_run_debug_binding(struct weston_compositor *compositor,
+				    struct weston_seat *seat, uint32_t time,
+				    uint32_t key,
+				    enum wl_keyboard_key_state state);
 
 int
 weston_environment_get_fd(const char *env);
diff --git a/src/shell.c b/src/shell.c
index b28353e..15c18ea 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3525,6 +3525,122 @@ fan_debug_repaint_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 	weston_compositor_damage_all(compositor);
 }
 
+struct debug_binding_grab {
+	struct wl_keyboard_grab grab;
+	struct weston_seat *seat;
+	uint32_t key[2];
+	int key_released[2];
+};
+
+static void
+debug_binding_key(struct wl_keyboard_grab *grab, uint32_t time,
+		  uint32_t key, uint32_t state)
+{
+	struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
+	struct wl_resource *resource;
+	struct wl_display *display;
+	uint32_t serial;
+	int send = 0, terminate = 0;
+	int check_binding = 1;
+	int i;
+
+	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) {
+		struct weston_compositor *ec = db->seat->compositor;
+
+		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) {
+		resource = grab->keyboard->focus_resource;
+
+		if (resource) {
+			display = wl_client_get_display(resource->client);
+			serial = wl_display_next_serial(display);
+			wl_keyboard_send_key(resource, serial, time, key, state);
+		}
+	}
+
+	if (terminate) {
+		wl_keyboard_end_grab(grab->keyboard);
+		free(db);
+	}
+}
+
+static void
+debug_binding_modifiers(struct wl_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;
+
+	resource = grab->keyboard->focus_resource;
+	if (!resource)
+		return;
+
+	wl_keyboard_send_modifiers(resource, serial, mods_depressed,
+				   mods_latched, mods_locked, group);
+}
+
+struct wl_keyboard_grab_interface debug_binding_keyboard_grab = {
+	debug_binding_key,
+	debug_binding_modifiers
+};
+
+static void
+debug_binding(struct wl_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 = (struct weston_seat *) seat;
+	grab->key[0] = key;
+	grab->grab.interface = &debug_binding_keyboard_grab;
+	wl_keyboard_start_grab(seat->keyboard, &grab->grab);
+}
+
 static void
 force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
 		   void *data)
@@ -3695,10 +3811,6 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
 					  ec);
 	weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
 				          backlight_binding, ec);
-	weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
-				          debug_repaint_binding, shell);
-	weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_ALT,
-				          fan_debug_repaint_binding, shell);
 	weston_compositor_add_key_binding(ec, KEY_K, mod,
 				          force_kill_binding, shell);
 	weston_compositor_add_key_binding(ec, KEY_UP, mod,
@@ -3722,6 +3834,14 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
 							  workspace_f_binding,
 							  shell);
 	}
+
+	/* Debug bindings */
+	weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
+					  debug_binding, shell);
+	weston_compositor_add_debug_binding(ec, KEY_R,
+					    debug_repaint_binding, shell);
+	weston_compositor_add_debug_binding(ec, KEY_F,
+					    fan_debug_repaint_binding, shell);
 }
 
 WL_EXPORT int
diff --git a/src/util.c b/src/util.c
index 306c797..2134392 100644
--- a/src/util.c
+++ b/src/util.c
@@ -359,6 +359,22 @@ weston_compositor_add_axis_binding(struct weston_compositor *compositor,
 	return binding;
 }
 
+WL_EXPORT struct weston_binding *
+weston_compositor_add_debug_binding(struct weston_compositor *compositor,
+				    uint32_t key,
+				    weston_key_binding_handler_t handler,
+				    void *data)
+{
+	struct weston_binding *binding;
+
+	binding = weston_compositor_add_binding(compositor, key, 0, 0, 0,
+						handler, data);
+
+	wl_list_insert(compositor->debug_binding_list.prev, &binding->link);
+
+	return binding;
+}
+
 WL_EXPORT void
 weston_binding_destroy(struct weston_binding *binding)
 {
@@ -498,6 +514,28 @@ weston_compositor_run_axis_binding(struct weston_compositor *compositor,
 }
 
 WL_EXPORT int
+weston_compositor_run_debug_binding(struct weston_compositor *compositor,
+				    struct weston_seat *seat,
+				    uint32_t time, uint32_t key,
+				    enum wl_keyboard_key_state state)
+{
+	weston_key_binding_handler_t handler;
+	struct weston_binding *binding;
+	int count = 0;
+
+	wl_list_for_each(binding, &compositor->debug_binding_list, link) {
+		if (key != binding->key)
+			continue;
+
+		count++;
+		handler = binding->handler;
+		handler(&seat->seat, time, key, binding->data);
+	}
+
+	return count;
+}
+
+WL_EXPORT int
 weston_environment_get_fd(const char *env)
 {
 	char *e, *end;
-- 
1.7.10.4



More information about the wayland-devel mailing list