#include <fcntl.h>
#include <getopt.h>
#include <sys/ioctl.h>
+#include <linux/limits.h>
#include <linux/input.h>
const struct key* lookup_key (const char *str, unsigned int len);
#define MAX_SCANCODES 1024
-/* If keymap file is given without a path, assume this one; must end with '/' * */
-#define DEFAULT_PATH "/lib/udev/keymaps/"
-
static int evdev_open(const char *dev)
{
int fd;
return r;
}
+static void set_key(int fd, const char* scancode_str, const char* keyname)
+{
+ unsigned scancode;
+ char *endptr;
+ char t[105] = "KEY_UNKNOWN";
+ const struct key *k;
+
+ scancode = (unsigned) strtol(scancode_str, &endptr, 0);
+ if (*endptr != '\0') {
+ fprintf(stderr, "ERROR: Invalid scancode\n");
+ exit(1);
+ }
+
+ snprintf(t, sizeof(t), "KEY_%s", keyname);
+
+ if (!(k = lookup_key(t, strlen(t)))) {
+ fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname);
+ exit(1);
+ }
+
+ if (evdev_set_keycode(fd, scancode, k->id) < 0)
+ fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n",
+ scancode, k->id);
+ else
+ printf("setting scancode 0x%2X to key code %i\n",
+ scancode, k->id);
+}
+
static int merge_table(int fd, const char *filename) {
int r = 0;
int line = 0;
{
static char result[PATH_MAX];
+ /* If keymap file is given without a path, assume udev directory; must end with '/' * */
if (!strchr(path, '/')) {
- snprintf(result, sizeof(result), "%s%s", DEFAULT_PATH, path);
+ snprintf(result, sizeof(result), "%s%s", LIBEXECDIR "/keymaps/", path);
return result;
}
return path;
static void print_key(struct input_event *event)
{
static int cur_scancode = 0;
+ const char *keyname;
/* save scan code for next EV_KEY event */
if (event->type == EV_MSC && event->code == MSC_SCAN)
cur_scancode = event->value;
/* key press */
- if (event->type == EV_KEY && event->value)
- printf("scan code: 0x%02X key code: %s\n", cur_scancode,
- format_keyname(key_names[event->code]));
+ if (event->type == EV_KEY && event->value) {
+ keyname = key_names[event->code];
+ if (keyname != NULL)
+ printf("scan code: 0x%02X key code: %s\n", cur_scancode,
+ format_keyname(key_names[event->code]));
+ else
+ printf("scan code: 0x%02X key code: %03X\n", cur_scancode,
+ event->code);
+ }
}
static void interactive(int fd)
ioctl(fd, EVIOCGRAB, 0);
}
+static void help(int error)
+{
+ const char* h = "Usage: keymap <event device> [<map file>]\n"
+ " keymap <event device> scancode keyname [...]\n"
+ " keymap -i <event device>\n";
+ if (error) {
+ fputs(h, stderr);
+ exit(2);
+ } else {
+ fputs(h, stdout);
+ exit(0);
+ }
+}
+
int main(int argc, char **argv)
{
static const struct option options[] = {
};
int fd = -1;
int opt_interactive = 0;
+ int i;
while (1) {
int option;
switch (option) {
case 'h':
- printf("Usage: keymap <event device> [<map file>]\n\n");
- return 0;
+ help(0);
case 'i':
opt_interactive = 1;
}
}
- if (argc < optind+1 || argc > optind+2) {
- fprintf(stderr, "Usage: keymap <event device> [<map file>]\n\n");
- return 2;
- }
+ if (argc < optind+1)
+ help (1);
if ((fd = evdev_open(argv[optind])) < 0)
return 3;
- if (argc == optind+2)
- merge_table(fd, default_keymap_path(argv[optind+1]));
- else {
+ /* one argument (device): dump or interactive */
+ if (argc == optind+1) {
if (opt_interactive)
interactive(fd);
else
dump_table(fd);
+ return 0;
}
- return 0;
+
+ /* two arguments (device, mapfile): set map file */
+ if (argc == optind+2) {
+ merge_table(fd, default_keymap_path(argv[optind+1]));
+ return 0;
+ }
+
+ /* more arguments (device, scancode/keyname pairs): set keys directly */
+ if ((argc - optind - 1) % 2 == 0) {
+ for (i = optind+1; i < argc; i += 2)
+ set_key(fd, argv[i], argv[i+1]);
+ return 0;
+ }
+
+ /* invalid number of arguments */
+ help(1);
+ return 1; /* not reached */
}