#include <asm/types.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <string.h> #include "input_keynames.h" static void print_error (const char *action, const char *file) __attribute__ ((noreturn)); static void print_error (const char *action, const char *file) { static const char msg [] = "\nERROR: could not "; write (0, msg, strlen(msg)); write (0, action, strlen(action)); write (0, " '", 2); write (0, file, strlen(file)); write (0, "'\n\n", 3); exit (-1); } static int parse_keyname (char *pos, char **nend, int limit) { int cmp, index; int l = 1; int r = sizeof (key_name) / sizeof (key_name[0]); if (limit < 5) return -1; while ((*pos == ' ' || *pos == '\t') && limit > 0) { (*nend)++; pos++; limit--; } if (pos [0] != 'K' || pos[1] != 'E' || pos[2] != 'Y' || pos[3] != '_') return -2; (*nend) += 4; pos += 4; limit -= 4; while (r >= l) { int len0, len1 = 0; index = (l + r) / 2; len0 = strlen(key_name[index-1].name); while (len1 < limit && isgraph(pos[len1])) len1++; cmp = strncmp (key_name[index-1].name, pos, strlen(key_name[index-1].name)); if (len0 < len1 && cmp == 0) cmp = -1; if (cmp == 0) { *nend = pos + strlen (key_name[index-1].name); if (**nend != '\n' && **nend != '\t' && **nend != ' ' && *nend != pos) return -3; return key_name[index-1].key; } if (cmp < 0) l = index + 1; else r = index - 1; if (r < l) { static const char msg [] = "\nunknown key '"; write (0, msg, strlen(msg)); write (0, pos-4, len1 + 4); write (0, "'\n", 2); } }; return -4; } const char usage [] = "\n\tusage: av7110_loadkeys [-i|--invert] [-a|--address <num>] keymap_filename.(rc5|rcmm)\n\n"; struct ir_setup { __u32 ir_config; __u16 keytab [256]; } __attribute__ ((packed)); int main (int argc, char **argv) { static struct ir_setup setup; int i, fd; size_t len; char *buf, *pos, *fname = NULL; for (i=1; i<argc; i++) { if (!strcmp("-i", argv[i]) || !strcmp("--invert", argv[i])) setup.ir_config |= 0x8000; else if (!strcmp("-a", argv[i]) || !strcmp("--address", argv[i])) { if (++i < argc) { setup.ir_config |= (atoi(argv[i]) & 0xff) << 16; setup.ir_config |= 0x4000; } } else fname = argv[i]; } if (!fname) { write (0, usage, strlen(usage)); exit (-1); } if (strncmp(".rcmm", fname + strlen(fname) - 5, 5) == 0) setup.ir_config |= 0x0001; else if (strncmp(".rc5", fname + strlen(fname) - 4, 4) != 0) { const char msg [] = "\nERROR: " "input filename must have suffix .rc5 or .rcmm\n"; write (0, msg, strlen(msg)); exit (-1); } if ((fd = open (fname, O_RDONLY)) < 0) print_error ("open", fname); len = lseek (fd, 0, SEEK_END); if (!(pos = buf = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0))) print_error ("mmap", fname); while (pos < buf + len) { int key, keycode; while (!isxdigit(*pos) && pos < buf + len) pos++; if (pos == buf + len) break; key = strtol (pos, &pos, 0); keycode = parse_keyname (pos, &pos, buf + len - pos); if (key < 0 || key > 0xff) { const char msg [] = "\nERROR: key must be in range 0 ... 0xff!\n\n"; write (0, msg, strlen(msg)); exit (-1); } if (keycode < 0) print_error ("parse", fname); setup.keytab[key] = keycode; } munmap (buf, len); close (fd); write (1, &setup, 4 + 256 * sizeof(__u16)); return 0; }