keymap.c revision 47ef94ac5f39db6c5c18be10afe32397a0a8d5cc
/*
* 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.
*
* 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 "keys-from-name.h"
#include "keys-to-name.h"
#include "util.h"
#define MAX_SCANCODES 1024
static int evdev_open(const char *dev)
{
int fd;
}
return -1;
}
return fd;
}
{
int codes[2];
return -2;
} else {
return -1;
}
}
return codes[1];
}
{
int codes[2];
return -1;
}
return 0;
}
{
int version;
return -1;
}
return 0;
}
{
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;
return result;
}
static int dump_table(int fd) {
int scancode, r = -1;
goto fail;
goto fail;
r = 0;
int keycode;
if (keycode == -2)
continue;
r = -1;
break;
}
else
}
fail:
return r;
}
{
unsigned scancode;
char *endptr;
char t[105] = "KEY_UNKNOWN";
const struct key *k;
if (*endptr != '\0') {
exit(1);
}
if (!(k = lookup_key(t, strlen(t)))) {
exit(1);
}
else
printf("setting scancode 0x%2X to key code %i\n",
}
int r = 0;
int line = 0;
while (!feof(f)) {
char s[256], *p;
if (!fgets(s, sizeof(s), f))
break;
line++;
p = s+strspn(s, "\t ");
if (*p == '#' || *p == '\n')
continue;
char t[105] = "KEY_UNKNOWN";
const struct key *k;
r = -1;
continue;
}
if (!(k = lookup_key(t, strlen(t)))) {
r = -1;
continue;
}
new_keycode = k->id;
}
r = -1;
goto fail;
}
r = -1;
goto fail;
}
if (new_keycode != old_keycode)
}
fail:
fclose(f);
return r;
}
/* read one event; return 1 if valid */
{
int ret;
if (ret < 0) {
perror("read");
return 0;
}
if (ret != sizeof(struct input_event)) {
return 0;
}
return 1;
}
{
const char *keyname;
/* ignore key release events */
if (has_key == 1)
return;
scancode);
return;
}
if (has_scan != 0)
else
printf("(no scan code received) ");
else
}
static void interactive(int fd)
{
struct input_event ev;
int has_scan; /* boolean */
int has_key; /* 0: none, 1: release, 2: press */
/* grab input device */
puts("Press ESC to finish, or Control-C if this device is not your primary keyboard");
/* 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 (has_scan) {
fputs("driver did not send SYN event in between key events; previous event:\n",
stderr);
has_key = 0;
}
has_scan = 1;
/*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */
}
if (has_key) {
fputs("driver did not send SYN event in between key events; previous event:\n",
stderr);
has_scan = 0;
}
/*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/
/* Stop on ESC */
break;
}
/*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/
}
}
/* release input device */
}
{
const char* h = "Usage: keymap <event device> [<map file>]\n"
" keymap <event device> scancode keyname [...]\n"
" keymap -i <event device>\n";
if (error) {
exit(2);
} else {
exit(0);
}
}
{
{}
};
int fd = -1;
int opt_interactive = 0;
int i;
while (1) {
int option;
if (option == -1)
break;
switch (option) {
case 'h':
help(0);
case 'i':
opt_interactive = 1;
break;
default:
return 1;
}
}
help (1);
return 3;
/* one argument (device): dump or interactive */
if (opt_interactive)
else
dump_table(fd);
return 0;
}
/* two arguments (device, mapfile): set map file */
/* Keymap file argument is a path */
if (f)
merge_table(fd, f);
else
} else {
/* Keymap file argument is a filename */
/* Open override file if present, otherwise default file */
char keymap_path[PATH_MAX];
FILE *f;
if (f) {
merge_table(fd, f);
} else {
if (f)
merge_table(fd, f);
else
}
}
return 0;
}
return 0;
}
/* invalid number of arguments */
help(1);
return 1; /* not reached */
}