[PATCH 2/4] Add xkb_names member plus config + X11 support

Kristian Høgsberg hoegsberg at gmail.com
Mon May 7 13:05:27 PDT 2012


On Tue, May 01, 2012 at 08:37:10PM +0100, Daniel Stone wrote:
> Add an xkb_names member to the base compositor info which contains the
> RMLVO to use when building an XKB keymap.  Add support for filling this
> from the config file or from the underlying X11 server, with the usual
> defaults.

I think we want to do this in the other direction.  The X server
shouldn't tell wayland which keymap to load (except if we're doing
rootless wayland under X).  We can add an event to the xserver wayland
protocol to let the compositor push the xkb info into the X server
when running under wayland.

The config file keys look good, though I'd drop the keymap_ prefix
since they're already under the keyboard section.

Kristian

> Signed-off-by: Daniel Stone <daniel at fooishbar.org>
> ---
>  src/compositor-x11.c |   41 +++++++++++++++++++++++++++++++++++++++++
>  src/compositor.c     |   43 +++++++++++++++++++++++++++++++++++++++++++
>  src/compositor.h     |    5 +++++
>  3 files changed, 89 insertions(+)
> 
> diff --git a/src/compositor-x11.c b/src/compositor-x11.c
> index 01194a8..1ca3a4b 100644
> --- a/src/compositor-x11.c
> +++ b/src/compositor-x11.c
> @@ -69,6 +69,7 @@ struct x11_compositor {
>  		xcb_atom_t		 string;
>  		xcb_atom_t		 utf8_string;
>  		xcb_atom_t		 cardinal;
> +		xcb_atom_t		 xkb_names;
>  	} atom;
>  };
>  
> @@ -713,6 +714,43 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
>  	return event != NULL;
>  }
>  
> +static void
> +x11_compositor_get_keymap(struct x11_compositor *c)
> +{
> +	xcb_get_property_cookie_t cookie;
> +	xcb_get_property_reply_t *reply;
> +	xcb_generic_error_t *error;
> +	const char *value_all, *value_part;
> +	int length_all, length_part;
> +
> +	cookie = xcb_get_property(c->conn, 0, c->screen->root,
> +				  c->atom.xkb_names, c->atom.string, 0, 1024);
> +	reply = xcb_get_property_reply(c->conn, cookie, &error);
> +	if (reply == NULL)
> +		return;
> +
> +	value_all = xcb_get_property_value(reply);
> +	length_all = xcb_get_property_value_length(reply);
> +	value_part = value_all;
> +
> +#define copy_prop_value(to) \
> +	length_part = strlen(value_part); \
> +	if (value_part + length_part > (value_all + length_all) && \
> +	    length_part > 0 && c->base.xkb_info.names.to == NULL) { \
> +		free(c->base.xkb_info.names.to); \
> +		c->base.xkb_info.names.to = strdup(value_part); \
> +	} \
> +	value_part += length_part + 1;
> +
> +	copy_prop_value(rules);
> +	copy_prop_value(model);
> +	copy_prop_value(layout);
> +	copy_prop_value(variant);
> +	copy_prop_value(options);
> +
> +#undef copy_prop_value
> +}
> +
>  #define F(field) offsetof(struct x11_compositor, field)
>  
>  static void
> @@ -731,6 +769,7 @@ x11_compositor_get_resources(struct x11_compositor *c)
>  		{ "STRING",		F(atom.string) },
>  		{ "UTF8_STRING",	F(atom.utf8_string) },
>  		{ "CARDINAL",		F(atom.cardinal) },
> +		{ "_XKB_RULES_NAMES",	F(atom.xkb_names) },
>  	};
>  
>  	xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
> @@ -762,6 +801,8 @@ x11_compositor_get_resources(struct x11_compositor *c)
>  			   pixmap, pixmap, 0, 0, 0,  0, 0, 0,  1, 1);
>  	xcb_free_gc(c->conn, gc);
>  	xcb_free_pixmap(c->conn, pixmap);
> +
> +	x11_compositor_get_keymap(c);
>  }
>  
>  static void
> diff --git a/src/compositor.c b/src/compositor.c
> index 1646905..a7e62a6 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -2561,6 +2561,29 @@ weston_compositor_shutdown(struct weston_compositor *ec)
>  	wl_event_loop_destroy(ec->input_loop);
>  }
>  
> +static int weston_compositor_xkb_init(struct weston_compositor *ec,
> +				      struct xkb_rule_names *names)
> +{
> +	ec->xkb_info.names = *names;
> +	if (!ec->xkb_info.names.rules)
> +		ec->xkb_info.names.rules = strdup("evdev");
> +	if (!ec->xkb_info.names.model)
> +		ec->xkb_info.names.model = strdup("pc105");
> +	if (!ec->xkb_info.names.layout)
> +		ec->xkb_info.names.layout = strdup("us");
> +
> +	return 0;
> +}
> +
> +static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
> +{
> +	free(ec->xkb_info.names.rules);
> +	free(ec->xkb_info.names.model);
> +	free(ec->xkb_info.names.layout);
> +	free(ec->xkb_info.names.variant);
> +	free(ec->xkb_info.names.options);
> +}
> +
>  static int on_term_signal(int signal_number, void *data)
>  {
>  	struct wl_display *display = data;
> @@ -2642,14 +2665,25 @@ int main(int argc, char *argv[])
>  	int32_t xserver = 0;
>  	char *socket_name = NULL;
>  	char *config_file;
> +	struct xkb_rule_names xkb_names;
>  
>  	const struct config_key shell_config_keys[] = {
>  		{ "type", CONFIG_KEY_STRING, &shell },
>  	};
>  
> +        const struct config_key keyboard_config_keys[] = {
> +		{ "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
> +		{ "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
> +		{ "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
> +		{ "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
> +		{ "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
> +        };
> +
>  	const struct config_section cs[] = {
>  		{ "shell",
>  		  shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
> +                { "keyboard",
> +                  keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
>  	};
>  
>  	const struct weston_option core_options[] = {
> @@ -2660,6 +2694,8 @@ int main(int argc, char *argv[])
>  		{ WESTON_OPTION_STRING, "module", 0, &module },
>  	};
>  
> +	memset(&xkb_names, 0, sizeof(xkb_names));
> +
>  	argc = parse_options(core_options,
>  			     ARRAY_LENGTH(core_options), argc, argv);
>  
> @@ -2712,6 +2748,11 @@ int main(int argc, char *argv[])
>  	if (argv[1])
>  		exit(EXIT_FAILURE);
>  
> +	if (weston_compositor_xkb_init(ec, &xkb_names) == -1) {
> +		fprintf(stderr, "failed to initialise keyboard support\n");
> +		exit(EXIT_FAILURE);
> +	}
> +
>  	ec->option_idle_time = idle_time;
>  	ec->idle_time = idle_time;
>  
> @@ -2757,6 +2798,8 @@ int main(int argc, char *argv[])
>  	for (i = ARRAY_LENGTH(signals); i;)
>  		wl_event_source_remove(signals[--i]);
>  
> +	weston_compositor_xkb_destroy(ec);
> +
>  	ec->destroy(ec);
>  	wl_display_destroy(display);
>  
> diff --git a/src/compositor.h b/src/compositor.h
> index a548f18..0b73575 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -25,6 +25,7 @@
>  #define _WAYLAND_SYSTEM_COMPOSITOR_H_
>  
>  #include <pixman.h>
> +#include <xkbcommon/xkbcommon.h>
>  #include <wayland-server.h>
>  
>  #include <GLES2/gl2.h>
> @@ -265,6 +266,10 @@ struct weston_compositor {
>  	int launcher_sock;
>  
>  	uint32_t output_id_pool;
> +
> +	struct {
> +		struct xkb_rule_names names;
> +	} xkb_info;
>  };
>  
>  #define MODIFIER_CTRL	(1 << 8)
> -- 
> 1.7.10
> 
> _______________________________________________
> 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