av7110_loadkeys.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include <asm/types.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/mman.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include "input_keynames.h"
  11. static
  12. void print_error (const char *action, const char *file)
  13. __attribute__ ((noreturn));
  14. static
  15. void print_error (const char *action, const char *file)
  16. {
  17. static const char msg [] = "\nERROR: could not ";
  18. write (0, msg, strlen(msg));
  19. write (0, action, strlen(action));
  20. write (0, " '", 2);
  21. write (0, file, strlen(file));
  22. write (0, "'\n\n", 3);
  23. exit (-1);
  24. }
  25. static
  26. int parse_keyname (char *pos, char **nend, int limit)
  27. {
  28. int cmp, _index;
  29. int l = 1;
  30. const struct input_key_name *kn;
  31. int r;
  32. if (limit < 5)
  33. return -1;
  34. while ((*pos == ' ' || *pos == '\t') && limit > 0) {
  35. (*nend)++;
  36. pos++;
  37. limit--;
  38. }
  39. if (pos[3] != '_')
  40. return -2;
  41. if (pos[0] == 'K' && pos[1] == 'E' && pos[2] == 'Y') {
  42. kn = key_name;
  43. r = sizeof (key_name) / sizeof (key_name[0]);
  44. }
  45. else if (pos[0] == 'B' && pos[1] == 'T' && pos[2] == 'N') {
  46. kn = btn_name;
  47. r = sizeof (btn_name) / sizeof (btn_name[0]);
  48. }
  49. else
  50. return -2;
  51. (*nend) += 4;
  52. pos += 4;
  53. limit -= 4;
  54. while (r >= l) {
  55. int len0, len1 = 0;
  56. _index = (l + r) / 2;
  57. len0 = strlen(kn[_index-1].name);
  58. while (len1 < limit && isgraph(pos[len1]))
  59. len1++;
  60. cmp = strncmp (kn[_index-1].name, pos,
  61. strlen(kn[_index-1].name));
  62. if (len0 < len1 && cmp == 0)
  63. cmp = -1;
  64. if (cmp == 0) {
  65. *nend = pos + strlen (kn[_index-1].name);
  66. if (**nend != '\n' &&
  67. **nend != '\t' &&
  68. **nend != ' ' &&
  69. *nend != pos)
  70. return -3;
  71. return kn[_index-1].key;
  72. }
  73. if (cmp < 0)
  74. l = _index + 1;
  75. else
  76. r = _index - 1;
  77. if (r < l) {
  78. static const char msg [] = "\nunknown key '";
  79. write (0, msg, strlen(msg));
  80. write (0, pos-4, len1 + 4);
  81. write (0, "'\n", 2);
  82. }
  83. };
  84. return -4;
  85. }
  86. const char usage [] = "\n\tusage: av7110_loadkeys [-i|--invert] [-a|--address <num>] keymap_filename.(rc5|rcmm)\n\n";
  87. struct ir_setup {
  88. __u32 ir_config;
  89. __u16 keytab [256];
  90. } __attribute__ ((packed));
  91. int main (int argc, char **argv)
  92. {
  93. static struct ir_setup setup;
  94. int i, fd;
  95. size_t len;
  96. char *buf, *pos, *fname = NULL;
  97. for (i=1; i<argc; i++) {
  98. if (!strcmp("-i", argv[i]) || !strcmp("--invert", argv[i]))
  99. setup.ir_config |= 0x8000;
  100. else if (!strcmp("-a", argv[i]) || !strcmp("--address", argv[i])) {
  101. if (++i < argc) {
  102. setup.ir_config |= (atoi(argv[i]) & 0xff) << 16;
  103. setup.ir_config |= 0x4000;
  104. }
  105. } else
  106. fname = argv[i];
  107. }
  108. if (!fname) {
  109. write (0, usage, strlen(usage));
  110. exit (-1);
  111. }
  112. if (strncmp(".rcmm", fname + strlen(fname) - 5, 5) == 0)
  113. setup.ir_config |= 0x0001;
  114. else if (strncmp(".rc5", fname + strlen(fname) - 4, 4) != 0) {
  115. const char msg [] = "\nERROR: "
  116. "input filename must have suffix .rc5 or .rcmm\n";
  117. write (0, msg, strlen(msg));
  118. exit (-1);
  119. }
  120. if ((fd = open (fname, O_RDONLY)) < 0)
  121. print_error ("open", fname);
  122. len = lseek (fd, 0, SEEK_END);
  123. if (!(pos = buf = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0)))
  124. print_error ("mmap", fname);
  125. while (pos < buf + len) {
  126. int key, keycode;
  127. while (!isxdigit(*pos) && pos < buf + len)
  128. pos++;
  129. if (pos == buf + len)
  130. break;
  131. key = strtol (pos, &pos, 0);
  132. keycode = parse_keyname (pos, &pos, buf + len - pos);
  133. if (key < 0 || key > 0xff) {
  134. const char msg [] =
  135. "\nERROR: key must be in range 0 ... 0xff!\n\n";
  136. write (0, msg, strlen(msg));
  137. exit (-1);
  138. }
  139. if (keycode < 0)
  140. print_error ("parse", fname);
  141. setup.keytab[key] = keycode;
  142. }
  143. munmap (buf, len);
  144. close (fd);
  145. write (1, &setup, 4 + 256 * sizeof(__u16));
  146. return 0;
  147. }