[kmscon-devel] [PATCH 1/2] uxkb: allow the user to use a predefined keymap file

Ran Benita ran234 at gmail.com
Sun Mar 10 03:02:59 PDT 2013


This adds an --xkb-keymap <FILE> option to kmscon. When given, kmscon
will try to compile the keymap from the file before trying the other
options (like the XkbKeymap option in xorg.conf).

This is useful for users who have a customized XKB keymap, which is
usually kept in a single file. Example, in X:
	xkbcomp $DISPLAY my_keymap.xkb
Customize my_keymap.xkb to your liking, and then in .xinitrc, or
xorg.conf:
	xkbcomp my_keymap.xkb $DISPLAY
Now you can also do this in kmscon.conf.

Additionally, lacking such an option, kmscon is quite difficult to use
without an installed xkeyboard-config package, which provides the
infrastructure for the "rules" configuration mechanism. We might even
want to distribute some plain xkb file as a last ditch, for
robustness, if even the default RMLVO fails... without a keyboard a
terminal is not very useful.

Signed-off-by: Ran Benita <ran234 at gmail.com>
---
 docs/man/kmscon.xml        |  8 ++++++++
 src/kmscon_conf.c          |  3 +++
 src/kmscon_conf.h          |  2 ++
 src/kmscon_seat.c          |  1 +
 src/uterm_input.c          |  3 ++-
 src/uterm_input.h          |  4 ++--
 src/uterm_input_internal.h |  3 ++-
 src/uterm_input_uxkb.c     | 30 +++++++++++++++++++++++++++++-
 tests/test_input.c         |  7 ++++++-
 tests/test_vt.c            |  2 +-
 10 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/docs/man/kmscon.xml b/docs/man/kmscon.xml
index 7777ede..4b3efea 100644
--- a/docs/man/kmscon.xml
+++ b/docs/man/kmscon.xml
@@ -300,6 +300,14 @@
       </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 (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
diff --git a/src/kmscon_conf.c b/src/kmscon_conf.c
index d960c42..42db227 100644
--- a/src/kmscon_conf.c
+++ b/src/kmscon_conf.c
@@ -105,6 +105,8 @@ static void print_help()
 		"\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>        [-]\n"
+		"\t                                 Use a predefined keymap for 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"
@@ -581,6 +583,7 @@ int kmscon_conf_new(struct conf_ctx **out)
 		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),
 
diff --git a/src/kmscon_conf.h b/src/kmscon_conf.h
index 4cb4789..113ea1a 100644
--- a/src/kmscon_conf.h
+++ b/src/kmscon_conf.h
@@ -104,6 +104,8 @@ struct kmscon_conf_t {
 	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 */
diff --git a/src/kmscon_seat.c b/src/kmscon_seat.c
index be8a5ab..a763b6a 100644
--- a/src/kmscon_seat.c
+++ b/src/kmscon_seat.c
@@ -680,6 +680,7 @@ int kmscon_seat_new(struct kmscon_seat **out,
 			      seat->conf->xkb_layout,
 			      seat->conf->xkb_variant,
 			      seat->conf->xkb_options,
+			      seat->conf->xkb_keymap,
 			      seat->conf->xkb_repeat_delay,
 			      seat->conf->xkb_repeat_rate);
 	if (ret)
diff --git a/src/uterm_input.c b/src/uterm_input.c
index 1ba8812..c248ee8 100644
--- a/src/uterm_input.c
+++ b/src/uterm_input.c
@@ -223,6 +223,7 @@ int uterm_input_new(struct uterm_input **out,
 		    const char *layout,
 		    const char *variant,
 		    const char *options,
+		    const char *keymap,
 		    unsigned int repeat_delay,
 		    unsigned int repeat_rate)
 {
@@ -255,7 +256,7 @@ int uterm_input_new(struct uterm_input **out,
 	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;
 
diff --git a/src/uterm_input.h b/src/uterm_input.h
index 36f5de2..43faccc 100644
--- a/src/uterm_input.h
+++ b/src/uterm_input.h
@@ -71,8 +71,8 @@ typedef void (*uterm_input_cb) (struct uterm_input *input,
 
 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);
 
diff --git a/src/uterm_input_internal.h b/src/uterm_input_internal.h
index 727af97..6491d33 100644
--- a/src/uterm_input_internal.h
+++ b/src/uterm_input_internal.h
@@ -86,7 +86,8 @@ int uxkb_desc_init(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);
diff --git a/src/uterm_input_uxkb.c b/src/uterm_input_uxkb.c
index 3053dfc..e2de3b5 100644
--- a/src/uterm_input_uxkb.c
+++ b/src/uterm_input_uxkb.c
@@ -44,7 +44,8 @@ int uxkb_desc_init(struct uterm_input *input,
 		   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 = {
@@ -54,6 +55,7 @@ int uxkb_desc_init(struct uterm_input *input,
 		.variant = variant,
 		.options = options,
 	};
+	FILE *keymap_file;
 
 	input->ctx = xkb_context_new(0);
 	if (!input->ctx) {
@@ -61,6 +63,32 @@ int uxkb_desc_init(struct uterm_input *input,
 		return -ENOMEM;
 	}
 
+	/* If a complete keymap file was given, first try that. */
+	if (keymap && *keymap) {
+		keymap_file = fopen(keymap, "re");
+		if (!keymap_file) {
+			log_warn("failed to open keymap file %s (%m), "
+				 "reverting to given xkb options",
+				 keymap);
+			goto keymap_from_names;
+		}
+
+		input->keymap = xkb_keymap_new_from_file(input->ctx,
+				   keymap_file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
+		fclose(keymap_file);
+
+		if (!input->keymap) {
+			log_warn("failed to create keymap from file %s, "
+				 "reverting to given xkb options",
+				 keymap);
+			goto keymap_from_names;
+		}
+
+		log_debug("new keyboard description from file (%s)", keymap);
+		return 0;
+	}
+
+keymap_from_names:
 	input->keymap = xkb_keymap_new_from_names(input->ctx, &rmlvo, 0);
 	if (!input->keymap) {
 		log_warn("failed to create keymap (%s, %s, %s, %s), "
diff --git a/tests/test_input.c b/tests/test_input.c
index 832c3b2..a8f51b1 100644
--- a/tests/test_input.c
+++ b/tests/test_input.c
@@ -52,6 +52,7 @@ struct {
 	char *xkb_layout;
 	char *xkb_variant;
 	char *xkb_options;
+	char *xkb_keymap;
 } input_conf;
 
 /* Pressing Ctrl-\ should toggle the capturing. */
@@ -119,6 +120,7 @@ static void monitor_event(struct uterm_monitor *mon,
 				      input_conf.xkb_layout,
 				      input_conf.xkb_variant,
 				      input_conf.xkb_options,
+				      input_conf.xkb_keymap,
 				      0, 0);
 		if (ret)
 			return;
@@ -166,7 +168,9 @@ static void print_help()
 		"\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>     [-]\n"
+		"\t                             Use a predefined keymap for input devices\n",
 		"test_input");
 	/*
 	 * 80 char line:
@@ -184,6 +188,7 @@ struct conf_option options[] = {
 	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)
diff --git a/tests/test_vt.c b/tests/test_vt.c
index 8423f0c..26c5ed6 100644
--- a/tests/test_vt.c
+++ b/tests/test_vt.c
@@ -113,7 +113,7 @@ 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;
 
-- 
1.8.1.5



More information about the kmscon-devel mailing list