This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/v4l-utils.git tree:

Subject: Improve it to better support IR
Author:  Mauro Carvalho Chehab <mche...@redhat.com>
Date:    Thu Mar 11 19:27:06 2010 -0300

This patch improves the tool by adding the capability to autodetect
the IR device, based on sysfs class. It also adds a proper parameter
handling to give more flexibility to the tool.

Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>

 utils/keytable/keytable.c |  393 ++++++++++++++++++++++++++++++++++-----------
 1 files changed, 302 insertions(+), 91 deletions(-)

---

http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=c0f920e3c2eb81a326d2a69e3ee2887214e1688b

diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c
index b94ee77..5f7dbd4 100644
--- a/utils/keytable/keytable.c
+++ b/utils/keytable/keytable.c
@@ -20,9 +20,187 @@
 #include <string.h>
 #include <linux/input.h>
 #include <sys/ioctl.h>
+#include <dirent.h>
+#include <argp.h>
 
 #include "parse.h"
 
+struct keytable {
+       int codes[2];
+       struct keytable *next;
+};
+
+static int parse_code(char *string)
+{
+       struct parse_key *p;
+
+       for (p = keynames; p->name != NULL; p++) {
+               if (!strcasecmp(p->name, string))
+                       return p->value;
+       }
+       return -1;
+}
+
+const char *argp_program_version = "IR keytable control version 0.1.0";
+const char *argp_program_bug_address = "Mauro Carvalho Chehab 
<mche...@redhat.com>";
+
+static const char doc[] = "\nAllows get/set IR keycode/scancode tables\n"
+       "You need to have read permissions on /dev/input for the program to 
work\n"
+       "\nOn the options bellow, the arguments are:\n"
+       "  DEV     - the /dev/input/event* device to control\n"
+       "  SYSDEV  - the ir class as found at /sys/class/irrcv\n"
+       "  TABLE   - a file wit a set of scancode=keycode value pairs\n"
+       "  SCANKEY - a set of scancode1=keycode1,scancode2=keycode2.. value 
pairs\n";
+
+static const struct argp_option options[] = {
+       {"verbose",     'v',    0,              0,      "enables debug 
messages", 0},
+       {"clear",       'c',    0,              0,      "clears the old table", 
0},
+       {"sysdev",      's',    "SYSDEV",       0,      "ir class device to 
control", 0},
+       {"device",      'd',    "DEV",          0,      "ir device to control", 
0},
+       {"get-table",   'g',    0,              0,      "reads the current 
scancode/keycode table", 0},
+       {"put-table",   'p',    "TABLE",        0,      "adds/replaces the 
scancodes to a new scancode/keycode table", 0},
+       {"set-key",     'k',    "SCANKEY",      0,      "Change scan/key 
pairs", 0},
+       { 0, 0, 0, 0, 0, 0 }
+};
+
+static const char args_doc[] =
+       "--device [/dev/input/event* device]\n"
+       "--sysdev [ir class (f. ex. irrcv0)]\n"
+       "[for using the irrcv0 sysdev]";
+
+
+static char *devclass = "irrcv0";
+static char *devname = NULL;
+static int read = 0;
+static int clear = 0;
+static int debug = 0;
+
+struct keytable keys = {
+       {0, 0}, NULL
+};
+
+struct keytable *nextkey = &keys;
+
+static error_t parse_keyfile(char *fname)
+{
+       FILE *fin;
+       int value;
+       char *scancode, *keycode, s[2048];
+
+       fin = fopen(fname, "r");
+       if (!fin) {
+               perror("opening keycode file");
+               return errno;
+       }
+
+       while (fgets(s, sizeof(s), fin)) {
+               scancode = strtok(s, "\n\t =:");
+               if (!scancode) {
+                       perror ("parsing input file scancode");
+                       return EINVAL;
+               }
+               if (!strcasecmp(scancode, "scancode")) {
+                       scancode = strtok(NULL,"\n\t =:");
+                       if (!scancode) {
+                               perror ("parsing input file scancode");
+                               return EINVAL;
+                       }
+               }
+
+               keycode=strtok(NULL, "\n\t =:(");
+               if (!keycode) {
+                       perror("parsing input file keycode");
+                       return EINVAL;
+               }
+
+               if (debug)
+                       fprintf(stderr, "parsing %s=%s:", scancode, keycode);
+               value=parse_code(keycode);
+               if (debug)
+                       fprintf(stderr, "\tvalue=%d\n",value);
+
+               if (value == -1) {
+                       value = strtol(keycode, NULL, 0);
+                       if (errno)
+                               perror("value");
+               }
+
+               nextkey->codes[0] = (unsigned) strtol(scancode, NULL, 0);
+               nextkey->codes[1] = (unsigned) value;
+               nextkey->next = calloc(1, sizeof(keys));
+               if (!nextkey->next)
+                       return ENOMEM;
+               nextkey = nextkey->next;
+       }
+       fclose(fin);
+
+       return 0;
+}
+
+static error_t parse_opt (int k, char *arg, struct argp_state *state)
+{
+       char *p;
+       long key;
+
+       switch (k) {
+       case 'v':
+               debug++;
+               break;
+       case 'c':
+               clear++;
+               break;
+       case 'd':
+               devname=arg;
+               break;
+       case 's':
+               devclass=arg;
+               break;
+       case 'g':
+               read++;
+               break;
+       case 'p':
+               return parse_keyfile(arg);
+       case 'k':
+               p = strtok(arg, ":=");
+               do {
+                       if (!p)
+                               return EINVAL;
+                       nextkey->codes[0] = strtol(p, NULL, 0);
+                       if (errno)
+                               return EINVAL;
+
+                       p = strtok(NULL, ",;");
+                       if (!p)
+                               return EINVAL;
+                       key = parse_code(p);
+                       if (key == -1) {
+                               key = strtol(p, NULL, 0);
+                               if (errno)
+                                       return EINVAL;
+                       }
+                       nextkey->codes[1] = key;
+
+                       nextkey->next = calloc(1, sizeof(keys));
+                       if (!nextkey->next)
+                                       return ENOMEM;
+                       nextkey = nextkey->next;
+
+                       p = strtok(NULL, ":=");
+               } while (p);
+               break;
+       default:
+               return ARGP_ERR_UNKNOWN;
+       }
+       return 0;
+}
+
+static struct argp argp = {
+       .options = options,
+       .parser = parse_opt,
+       .args_doc = args_doc,
+       .doc = doc,
+};
+
 static void prtcode (int *codes)
 {
        struct parse_key *p;
@@ -40,68 +218,108 @@ static void prtcode (int *codes)
                printf("scancode %d = 0x%02x\n", codes[0], codes[1]);
 }
 
-static int parse_code(char *string)
+static char *find_device(void)
 {
-       struct parse_key *p;
+       DIR             *dir;
+       struct dirent   *entry;
+       FILE            *fp;
+       char            dname[256], *event = "event", *name = NULL;
+       char            s[256];
+       int             found = 0;
+       char            *DEV = "/dev/";
 
-       for (p=keynames;p->name!=NULL;p++) {
-               if (!strcasecmp(p->name, string)) {
-                       return p->value;
-               }
+       /*
+        * Get event sysfs node
+        */
+       snprintf(dname, sizeof(dname) - 30, "/sys/class/irrcv/%s/input/",
+                devclass);
+       dir = opendir(dname);
+       if (!dir) {
+               perror(dname);
+               return NULL;
        }
-       return -1;
-}
-
-int main (int argc, char *argv[])
-{
-       int fd;
-       unsigned int i, j;
-       int codes[2];
 
-       if (argc<2 || argc>4) {
-               printf ("usage: %s <device> to get table; or\n"
-                       "       %s <device> <scancode> <keycode>\n"
-                       "       %s <device> 
<keycode_file>\n",*argv,*argv,*argv);
-               return -1;
+       entry = readdir(dir);
+       while (entry) {
+               if (!strncmp(entry->d_name, event, strlen(event))) {
+                       strcat(dname, entry->d_name);
+                       found = 1;
+                       break;
+               }
+               entry = readdir(dir);
        }
+       closedir(dir);
 
-       if ((fd = open(argv[1], O_RDONLY)) < 0) {
-               perror("Couldn't open input device");
-               return(-1);
+       if (!found) {
+               fprintf(stderr, "Couldn't find event device. Too old driver?");
+               return NULL;
        }
+       if (debug)
+               fprintf(stderr, "Event sysfs node is %s\n", dname);
 
-       if (argc==4) {
-               int value;
-
-               value=parse_code(argv[3]);
+       strcat(dname, "/uevent");
 
-               if (value==-1) {
-                       value = strtol(argv[3], NULL, 0);
-                       if (errno)
-                               perror("value");
+       fp = fopen (dname, "r");
+       if (!fp) {
+               perror (dname);
+               return NULL;
+       }
+       while (fgets(s, sizeof(s), fp)) {
+               char *p = strtok(s, "=");
+               if (!strcmp(p, "DEVNAME")) {
+                       p = strtok(NULL, "\n");
+                       if (!p) {
+                               fprintf(stderr, "Error on uevent 
information\n");
+                               fclose (fp);
+                               return NULL;
+                       }
+                       name = malloc(strlen(p) + sizeof(DEV) + 1);
+                       if (!name) {
+                               fprintf(stderr, "No memory\n");
+                               fclose (fp);
+                               return NULL;
+                       }
+                       strcpy(name, DEV);
+                       strcat(name, p);
+                       break;
                }
+       }
+       fclose (fp);
 
-               codes [0] = (unsigned) strtol(argv[2], NULL, 0);
-               codes [1] = (unsigned) value;
+       if (debug)
+               fprintf(stderr, "input device is %s\n", name);
 
-               if(ioctl(fd, EVIOCSKEYCODE, codes))
-                       perror ("EVIOCSKEYCODE");
+       return name;
+}
 
-               if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
-                       prtcode(codes);
-               return 0;
-       }
+int main (int argc, char *argv[])
+{
+       int fd;
+       unsigned int i, j;
+       int dev_from_class = 0, done = 0;
 
-       if (argc==3) {
-               FILE *fin;
-               int value;
-               char *scancode, *keycode, s[2048];
+       argp_parse (&argp, argc, argv, 0, 0, 0);
 
-               fin=fopen(argv[2],"r");
-               if (fin==NULL) {
-                       perror ("opening keycode file");
+       if (!devname) {
+               devname = find_device();
+               if (!devname)
                        return -1;
-               }
+               dev_from_class++;
+       }
+       if (debug)
+               fprintf(stderr, "Opening %s\n",devname);
+       if ((fd = open(devname, O_RDONLY)) < 0) {
+               perror(devname);
+               return -1;
+       }
+       if (dev_from_class)
+               free(devname);
+
+       /*
+        * First step: clear, if --clear is specified
+        */
+       if (clear) {
+               int codes[2];
 
                /* Clears old table */
                for (j = 0; j < 256; j++) {
@@ -111,60 +329,53 @@ int main (int argc, char *argv[])
                                ioctl(fd, EVIOCSKEYCODE, codes);
                        }
                }
+               done++;
+       }
 
-               while (fgets(s,sizeof(s),fin)) {
-                       scancode=strtok(s,"\n\t =:");
-                       if (!scancode) {
-                               perror ("parsing input file scancode");
-                               return -1;
-                       }
-                       if (!strcasecmp(scancode, "scancode")) {
-                               scancode = strtok(NULL,"\n\t =:");
-                               if (!scancode) {
-                                       perror ("parsing input file scancode");
-                                       return -1;
-                               }
-                       }
-
-                       keycode=strtok(NULL,"\n\t =:(");
-                       if (!keycode) {
-                               perror ("parsing input file keycode");
-                               return -1;
-                       }
+       /*
+        * Second step: stores key tables from file or from commandline
+        */
+       nextkey = &keys;
+       while (nextkey->next) {
+               int value;
+               struct keytable *old;
 
-                       // printf ("parsing %s=%s:", scancode, keycode);
-                       value=parse_code(keycode);
-                       // printf ("\tvalue=%d\n",value);
+               if (debug)
+                       fprintf(stderr, "\t%04x=%04x\n",
+                              nextkey->codes[0], nextkey->codes[1]);
 
-                       if (value==-1) {
-                               value = strtol(keycode, NULL, 0);
-                               if (errno)
-                                       perror("value");
-                       }
+               if (ioctl(fd, EVIOCSKEYCODE, nextkey->codes)) {
+                       fprintf(stderr,
+                               "Setting scancode 0x%04x with 0x%04x via ",
+                               nextkey->codes[0], nextkey->codes[1]);
+                       perror ("EVIOCSKEYCODE");
+               }
+               old = nextkey;
+               nextkey = nextkey->next;
+               if (old != &keys)
+                       free(old);
+               done++;
+       }
 
-                       codes [0] = (unsigned) strtol(scancode, NULL, 0);
-                       codes [1] = (unsigned) value;
+       /*
+        * Third step: display current keytable
+        */
+       if (read) {
+               done++;
+               for (j = 0; j < 256; j++) {
+                       for (i = 0; i < 256; i++) {
+                               int codes[2];
 
-                       // printf("\t%04x=%04x\n",codes[0], codes[1]);
-                       if(ioctl(fd, EVIOCSKEYCODE, codes)) {
-                               fprintf(stderr, "Setting scancode 0x%04x with 
0x%04x via ",codes[0], codes[1]);
-                               perror ("EVIOCSKEYCODE");
+                               codes[0] = (j << 8) | i;
+                               if (!ioctl(fd, EVIOCGKEYCODE, codes) && 
codes[1] != KEY_RESERVED)
+                                       prtcode(codes);
                        }
-
-                       if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
-                               prtcode(codes);
                }
-               return 0;
        }
 
-       /* Get scancode table */
-       for (j = 0; j < 256; j++) {
-               for (i = 0; i < 256; i++) {
-                       codes[0] = (j << 8) | i;
-                       if (!ioctl(fd, EVIOCGKEYCODE, codes) && codes[1] != 
KEY_RESERVED)
-                               prtcode(codes);
-               }
+       if (!done) {
+               argp_help(&argp, stderr, ARGP_HELP_SEE, argv[0]);
        }
+
        return 0;
 }
-

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to