Overriding a keymap file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sometimes the administrator wants to override the relevant file
in (on Debian:) /lib/udev/keymaps/.  It would be convenient if this
could be done by creating a separate file under SYSCONFDIR,
i.e., under /etc, which would contain only the entries that the
admin wants to change.

For example, /lib/udev/keymaps/module-lenovo contains 16 lines.
Suppose the admin wants to change

    0x13 zoom

to

    0x13 search

If he changes /lib/udev/keymaps directly then his changes will
be overwritten by his packaging system on the next upgrade
of the udev package.  So that is not a reasonable course of action.

He does have the alternative of adding a udev rules file to
(on Debian) /etc/udev/rules.d but this is much less convenient
since it has to duplicate significant amounts of udev code from
(on Debian) /lib/udev/rules.d/95-keymap.rules.

As an example of how support for a "keymap override" file
could be added I attach a patch.  It has been tested and works
on my Ubuntu 11.04 system but I don't know how well it conforms
to applicable coding standards.

Should "keymap override" support be added to udev?  And is my
patch anything like the right way to do it?

Comments most welcome.
-- 
Thomas Hood
--- extras/keymap/keymap.c_ORIG	2011-07-21 15:01:08.830054279 +0200
+++ extras/keymap/keymap.c	2011-07-21 14:48:45.322209254 +0200
@@ -184,14 +184,15 @@
 			scancode, k->id);
 }
 
-static int merge_table(int fd, const char *filename) {
+static int merge_table(int fd, const char *filename, int report_fopen_fail) {
 	int r = 0;
 	int line = 0;
 	FILE* f;
 
 	f = fopen(filename, "r");
 	if (!f) {
-		perror(filename);
+		if (report_fopen_fail)
+			perror(filename);
 		r = -1;
 		goto fail;
 	}
@@ -250,7 +251,7 @@
 {
 	static char result[PATH_MAX];
 
-	/* If keymap file is given without a path, assume udev directory; must end with '/' * */
+	/* If keymap file is given without a path, assume udev default directory; must end with '/' * */
 	if (!strchr(path, '/')) {
 		snprintf(result, sizeof(result), "%s%s", LIBEXECDIR "/keymaps/", path);
 		return result;
@@ -258,6 +259,18 @@
 	return path;
 }
 
+static const char* override_keymap_path(const char* path)
+{
+	static char result[PATH_MAX];
+
+	/* If keymap file is given without a path, assume udev override directory; must end with '/' * */
+	if (!strchr(path, '/')) {
+		snprintf(result, sizeof(result), "%s%s", SYSCONFDIR "/udev/keymaps/", path);
+		return result;
+	}
+	return path;
+}
+
 /* read one event; return 1 if valid */
 static int read_event(int fd, struct input_event* ev)
 {
@@ -424,7 +437,8 @@
 
 	/* two arguments (device, mapfile): set map file */
 	if (argc == optind+2) {
-		merge_table(fd, default_keymap_path(argv[optind+1]));
+		merge_table(fd, default_keymap_path(argv[optind+1]), 1);
+		merge_table(fd, override_keymap_path(argv[optind+1]), 0);
 		return 0;
 	}
 

[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux