xcb_atom_t string;
xcb_atom_t utf8_string;
xcb_atom_t cardinal;
+ xcb_atom_t xkb_names;
} atom;
};
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
{ "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)];
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
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;
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[] = {
{ WESTON_OPTION_STRING, "module", 0, &module },
};
+ memset(&xkb_names, 0, sizeof(xkb_names));
+
argc = parse_options(core_options,
ARRAY_LENGTH(core_options), argc, 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;
for (i = ARRAY_LENGTH(signals); i;)
wl_event_source_remove(signals[--i]);
+ weston_compositor_xkb_destroy(ec);
+
ec->destroy(ec);
wl_display_destroy(display);