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

Daniel Stone daniel at fooishbar.org
Tue May 1 12:37:10 PDT 2012


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.

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



More information about the wayland-devel mailing list