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

Kristian Høgsberg hoegsberg at gmail.com
Thu Nov 8 11:00:19 PST 2012


On Thu, Nov 08, 2012 at 05:20:45PM +0200, Ander Conselvan de Oliveira wrote:
> 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.

Very nice, this and the next two committed.

Kristian

> ---
>  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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list