</varlistentry>
<varlistentry>
+ <term><option>--xkb-keymap {file}</option></term>
+ <listitem>
+ <para>Path to a single predefined keymap file. This takes precedence
+ over the above options. An empty path "" is interpreted as not
+ using a keymap. (default: not used)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--xkb-repeat-delay {delay}</option></term>
<listitem>
<para>Delay after key was pressed until key-repeat starts (in
"\t --xkb-layout <layout> [-] Set XkbLayout for input devices\n"
"\t --xkb-variant <variant> [-] Set XkbVariant for input devices\n"
"\t --xkb-options <options> [-] Set XkbOptions for input devices\n"
+ "\t --xkb-keymap <FILE> [-] Use a predefined keymap for\n"
+ "\t input devices\n"
"\t --xkb-repeat-delay <msecs> [250]\n"
"\t Initial delay for key-repeat in ms\n"
"\t --xkb-repeat-rate <msecs> [50]\n"
CONF_OPTION_STRING(0, "xkb-layout", &conf->xkb_layout, ""),
CONF_OPTION_STRING(0, "xkb-variant", &conf->xkb_variant, ""),
CONF_OPTION_STRING(0, "xkb-options", &conf->xkb_options, ""),
+ CONF_OPTION_STRING(0, "xkb-keymap", &conf->xkb_keymap, ""),
CONF_OPTION_UINT(0, "xkb-repeat-delay", &conf->xkb_repeat_delay, 250),
CONF_OPTION_UINT(0, "xkb-repeat-rate", &conf->xkb_repeat_rate, 50),
char *xkb_variant;
/* input KBD options */
char *xkb_options;
+ /* input predefined KBD keymap */
+ char *xkb_keymap;
/* keyboard key-repeat delay */
unsigned int xkb_repeat_delay;
/* keyboard key-repeat rate */
{
struct kmscon_seat *seat;
int ret;
+ char *keymap;
if (!out || !eloop || !vtm || !seatname)
return -EINVAL;
goto err_conf;
}
+ /* TODO: The XKB-API currently requires zero-terminated strings as
+ * keymap input. Hence, we have to read it in instead of using mmap().
+ * We should fix this upstream! */
+ keymap = NULL;
+ if (seat->conf->xkb_keymap && *seat->conf->xkb_keymap) {
+ ret = shl_read_file(seat->conf->xkb_keymap, &keymap, NULL);
+ if (ret)
+ log_error("cannot read keymap file %s: %d",
+ seat->conf->xkb_keymap, ret);
+ }
+
ret = uterm_input_new(&seat->input, seat->eloop,
seat->conf->xkb_model,
seat->conf->xkb_layout,
seat->conf->xkb_variant,
seat->conf->xkb_options,
+ keymap,
seat->conf->xkb_repeat_delay,
seat->conf->xkb_repeat_rate);
+ free(keymap);
+
if (ret)
goto err_conf;
const char *layout,
const char *variant,
const char *options,
+ const char *keymap,
unsigned int repeat_delay,
unsigned int repeat_rate)
{
if (ret)
goto err_free;
- ret = uxkb_desc_init(input, model, layout, variant, options);
+ ret = uxkb_desc_init(input, model, layout, variant, options, keymap);
if (ret)
goto err_hook;
int uterm_input_new(struct uterm_input **out, struct ev_eloop *eloop,
const char *model, const char *layout, const char *variant,
- const char *options, unsigned int repeat_delay,
- unsigned int repeat_rate);
+ const char *options, const char *keymap,
+ unsigned int repeat_delay, unsigned int repeat_rate);
void uterm_input_ref(struct uterm_input *input);
void uterm_input_unref(struct uterm_input *input);
const char *model,
const char *layout,
const char *variant,
- const char *options);
+ const char *options,
+ const char *keymap);
void uxkb_desc_destroy(struct uterm_input *input);
int uxkb_dev_init(struct uterm_input_dev *dev);
const char *model,
const char *layout,
const char *variant,
- const char *options)
+ const char *options,
+ const char *keymap)
{
int ret;
struct xkb_rule_names rmlvo = {
return -ENOMEM;
}
+ /* If a complete keymap file was given, first try that. */
+ if (keymap && *keymap) {
+ input->keymap = xkb_keymap_new_from_string(input->ctx,
+ keymap, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
+ if (input->keymap) {
+ log_debug("new keyboard description from memory");
+ return 0;
+ }
+
+ log_warn("cannot parse keymap, reverting to rmlvo");
+ }
+
input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0);
if (!input->keymap) {
log_warn("failed to create keymap (%s, %s, %s, %s), "
char *xkb_layout;
char *xkb_variant;
char *xkb_options;
+ char *xkb_keymap;
} input_conf;
/* Pressing Ctrl-\ should toggle the capturing. */
void *data)
{
int ret;
+ char *keymap;
if (ev->type == UTERM_MONITOR_NEW_SEAT) {
if (strcmp(ev->seat_name, "seat0"))
return;
+ keymap = NULL;
+ if (input_conf.xkb_keymap && *input_conf.xkb_keymap) {
+ ret = shl_read_file(input_conf.xkb_keymap, &keymap,
+ NULL);
+ if (ret)
+ log_error("cannot read keymap file %s: %d",
+ input_conf.xkb_keymap, ret);
+ }
+
ret = uterm_input_new(&input, eloop,
input_conf.xkb_model,
input_conf.xkb_layout,
input_conf.xkb_variant,
input_conf.xkb_options,
+ keymap,
0, 0);
if (ret)
return;
"\t --xkb-model <model> [-] Set XkbModel for input devices\n"
"\t --xkb-layout <layout> [-] Set XkbLayout for input devices\n"
"\t --xkb-variant <variant> [-] Set XkbVariant for input devices\n"
- "\t --xkb-options <options> [-] Set XkbOptions for input devices\n",
+ "\t --xkb-options <options> [-] Set XkbOptions for input devices\n"
+ "\t --xkb-keymap <FILE> [-] Use a predefined keymap for\n"
+ "\t input devices\n",
"test_input");
/*
* 80 char line:
CONF_OPTION_STRING(0, "xkb-layout", &input_conf.xkb_layout, ""),
CONF_OPTION_STRING(0, "xkb-variant", &input_conf.xkb_variant, ""),
CONF_OPTION_STRING(0, "xkb-options", &input_conf.xkb_options, ""),
+ CONF_OPTION_STRING(0, "xkb-keymap", &input_conf.xkb_keymap, ""),
};
int main(int argc, char **argv)
if (ret)
goto err_exit;
- ret = uterm_input_new(&input, eloop, "", "", "", "", 0, 0);
+ ret = uterm_input_new(&input, eloop, "", "", "", "", "", 0, 0);
if (ret)
goto err_vtm;