/*
 * keymap - dump keymap of an evdev device or set a new keymap from a file
 *
 * Based on keyfuzz by Lennart Poettering <mzqrovna@0pointer.net>
 * Adapted for udev-extras by Martin Pitt <martin.pitt@ubuntu.com>
 *
 * Copyright (C) 2006, Lennart Poettering
 * Copyright (C) 2009, Canonical Ltd.
 *
 * keymap is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * keymap is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with keymap; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#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);

#include "keys-from-name.h"
#include "keys-to-name.h"

#define MAX_SCANCODES 1024

static int evdev_open(const char *dev)
{
	int fd;
	char fn[PATH_MAX];

	if (strncmp(dev, "/dev", 4) != 0) {
		snprintf(fn, sizeof(fn), "/dev/%s", dev);
		dev = fn;
	}

	if ((fd = open(dev, O_RDWR)) < 0) {
		fprintf(stderr, "error open('%s'): %m\n", dev);
		return -1;
	}
	return fd;
}

static int evdev_get_keycode(int fd, int scancode, int e)
{
	int codes[2];

	codes[0] = scancode;
	if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) {
		if (e && errno == EINVAL) {
			return -2;
		} else {
			fprintf(stderr, "EVIOCGKEYCODE: %m\n");
			return -1;
		}
	}
	return codes[1];
}

static int evdev_set_keycode(int fd, int scancode, int keycode)
{
	int codes[2];

	codes[0] = scancode;
	codes[1] = keycode;

	if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) {
		fprintf(stderr, "EVIOCSKEYCODE: %m\n");
		return -1;
	}
	return 0;
}

static int evdev_driver_version(int fd, char *v, size_t l)
{
	int version;

	if (ioctl(fd, EVIOCGVERSION, &version)) {
		fprintf(stderr, "EVIOCGVERSION: %m\n");
		return -1;
	}

	snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff);
	return 0;
}

static int evdev_device_name(int fd, char *n, size_t l)
{
	if (ioctl(fd, EVIOCGNAME(l), n) < 0) {
		fprintf(stderr, "EVIOCGNAME: %m\n");
		return -1;
	}
	return 0;
}

/* Return a lower-case string with KEY_ prefix removed */
static const char* format_keyname(const char* key) {
	static char result[101];
	const char* s;
	int len;

	for (s = key+4, len = 0; *s && len < 100; ++len, ++s)
		result[len] = tolower(*s);
	result[len] = '\0';
	return result;
}

static int dump_table(int fd) {
	char version[256], name[256];
	int scancode, r = -1;

	if (evdev_driver_version(fd, version, sizeof(version)) < 0)
		goto fail;

	if (evdev_device_name(fd, name, sizeof(name)) < 0)
		goto fail;

	printf("### evdev %s, driver '%s'\n", version, name);

	r = 0;
	for (scancode = 0; scancode < MAX_SCANCODES; scancode++) {
		int keycode;

		if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) {
			if (keycode != -2)
				r = -1;
			break;
		}

		if (keycode < KEY_MAX && key_names[keycode])
			printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode]));
		else
			printf("0x%03x 0x%03x\n", scancode, keycode);
	}
fail:
	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;
	FILE* f;

	f = fopen(filename, "r");
	if (!f) {
		perror(filename);
		r = -1;
		goto fail;
	}

	while (!feof(f)) {
		char s[256], *p;
		int scancode, new_keycode, old_keycode;

		if (!fgets(s, sizeof(s), f))
			break;

		line++;
		p = s+strspn(s, "\t ");
		if (*p == '#' || *p == '\n')
			continue;

		if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) {
			char t[105] = "KEY_UNKNOWN";
			const struct key *k;

			if (sscanf(p, "%i %100s", &scancode, t+4) != 2) {
				fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line);
				r = -1;
				continue;
			}

			if (!(k = lookup_key(t, strlen(t)))) {
				fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line);
				r = -1;
				continue;
			}

			new_keycode = k->id;
		}


		if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) {
			r = -1;
			goto fail;
		}

		if (evdev_set_keycode(fd, scancode, new_keycode) < 0) {
			r = -1;
			goto fail;
		}

		if (new_keycode != old_keycode)
			fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n",
				scancode, new_keycode, old_keycode);
	}
fail:
	return r;
}

static const char* default_keymap_path(const char* path)
{
	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", LIBEXECDIR "/keymaps/", path);
		return result;
	}
	return path;
}

/* read one event; return 1 if valid */
static int read_event(int fd, struct input_event* ev)
{
	int ret;
	ret = read(fd, ev, sizeof(struct input_event));

	if (ret < 0) {
		perror("read");
		return 0;
	}
	if (ret != sizeof(struct input_event)) {
		fprintf(stderr, "did not get enough data for event struct, aborting\n");
		return 0;
	}

	return 1;
}

static void print_key(uint32_t scancode, uint16_t keycode, int has_scan, int has_key)
{
	const char *keyname;

	/* ignore key release events */
	if (has_key == 1)
		return;

	if (has_key == 0 && has_scan != 0) {
		fprintf(stderr, "got scan code event 0x%02X without a key code event\n",
			scancode);
		return;
	}

	if (has_scan != 0)
		printf("scan code: 0x%02X   ", scancode);
	else
		printf("(no scan code received)  ");

	keyname = key_names[keycode];
	if (keyname != NULL)
		printf("key code: %s\n", format_keyname(keyname));
	else
		printf("key code: %03X\n", keycode);
}

static void interactive(int fd)
{
	struct input_event ev;
	uint32_t last_scan = 0;
	uint16_t last_key = 0;
	int has_scan; /* boolean */
	int has_key; /* 0: none, 1: release, 2: press */

	/* grab input device */
	ioctl(fd, EVIOCGRAB, 1);
	puts("Press ESC to finish, or Control-C if this device is not your primary keyboard");

	has_scan = has_key = 0;
	while (read_event(fd, &ev)) {
		/* Drivers usually send the scan code first, then the key code,
		 * then a SYN. Some drivers (like thinkpad_acpi) send the key
		 * code first, and some drivers might not send SYN events, so
		 * keep a robust state machine which can deal with any of those
		 */

		if (ev.type == EV_MSC && ev.code == MSC_SCAN) {
			if (has_scan) {
				fputs("driver did not send SYN event in between key events; previous event:\n",
				      stderr);
				print_key(last_scan, last_key, has_scan, has_key);
				has_key = 0;
			}

			last_scan = ev.value;
			has_scan = 1;
			/*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */
		}
		else if (ev.type == EV_KEY) {
			if (has_key) {
				fputs("driver did not send SYN event in between key events; previous event:\n",
				      stderr);
				print_key(last_scan, last_key, has_scan, has_key);
				has_scan = 0;
			}

		       	last_key = ev.code;
			has_key = 1 + ev.value;
			/*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/

			/* Stop on ESC */
			if (ev.code == KEY_ESC && ev.value == 0)
				break;
		}
		else if (ev.type == EV_SYN) {
			/*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/
			print_key(last_scan, last_key, has_scan, has_key);

			has_scan = has_key = 0;
		}

	}

	/* release input device */
	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[] = {
		{ "help", no_argument, NULL, 'h' },
		{ "interactive", no_argument, NULL, 'i' },
		{}
	};
	int fd = -1;
	int opt_interactive = 0;
	int i;

	while (1) {
		int option;

		option = getopt_long(argc, argv, "hi", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'h':
		        help(0);

		case 'i':
			opt_interactive = 1;
			break;
		default:
			return 1;
		}
	}

	if (argc < optind+1)
		help (1);

	if ((fd = evdev_open(argv[optind])) < 0)
		return 3;

	/* one argument (device): dump or interactive */
	if (argc == optind+1) {
		if (opt_interactive)
			interactive(fd);
		else
			dump_table(fd);
		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 */
}
