1.. Permission is granted to copy, distribute and/or modify this
2.. document under the terms of the GNU Free Documentation License,
3.. Version 1.1 or any later version published by the Free Software
4.. Foundation, with no Invariant Sections, no Front-Cover Texts
5.. and no Back-Cover Texts. A copy of the license is included at
6.. Documentation/userspace-api/media/fdl-appendix.rst.
7..
8.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
9
10file: uapi/v4l/keytable.c
11=========================
12
13.. code-block:: c
14
15    /* keytable.c - This program allows checking/replacing keys at IR
16
17       Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.org>
18
19       This program is free software; you can redistribute it and/or modify
20       it under the terms of the GNU General Public License as published by
21       the Free Software Foundation, version 2 of the License.
22
23       This program is distributed in the hope that it will be useful,
24       but WITHOUT ANY WARRANTY; without even the implied warranty of
25       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26       GNU General Public License for more details.
27     */
28
29    #include <ctype.h>
30    #include <errno.h>
31    #include <fcntl.h>
32    #include <stdio.h>
33    #include <stdlib.h>
34    #include <string.h>
35    #include <linux/input.h>
36    #include <sys/ioctl.h>
37
38    #include "parse.h"
39
40    void prtcode (int *codes)
41    {
42	    struct parse_key *p;
43
44	    for (p=keynames;p->name!=NULL;p++) {
45		    if (p->value == (unsigned)codes[1]) {
46			    printf("scancode 0x%04x = %s (0x%02x)\\n", codes[0], p->name, codes[1]);
47			    return;
48		    }
49	    }
50
51	    if (isprint (codes[1]))
52		    printf("scancode %d = '%c' (0x%02x)\\n", codes[0], codes[1], codes[1]);
53	    else
54		    printf("scancode %d = 0x%02x\\n", codes[0], codes[1]);
55    }
56
57    int parse_code(char *string)
58    {
59	    struct parse_key *p;
60
61	    for (p=keynames;p->name!=NULL;p++) {
62		    if (!strcasecmp(p->name, string)) {
63			    return p->value;
64		    }
65	    }
66	    return -1;
67    }
68
69    int main (int argc, char *argv[])
70    {
71	    int fd;
72	    unsigned int i, j;
73	    int codes[2];
74
75	    if (argc<2 || argc>4) {
76		    printf ("usage: %s <device> to get table; or\\n"
77			    "       %s <device> <scancode> <keycode>\\n"
78			    "       %s <device> <keycode_file>n",*argv,*argv,*argv);
79		    return -1;
80	    }
81
82	    if ((fd = open(argv[1], O_RDONLY)) < 0) {
83		    perror("Couldn't open input device");
84		    return(-1);
85	    }
86
87	    if (argc==4) {
88		    int value;
89
90		    value=parse_code(argv[3]);
91
92		    if (value==-1) {
93			    value = strtol(argv[3], NULL, 0);
94			    if (errno)
95				    perror("value");
96		    }
97
98		    codes [0] = (unsigned) strtol(argv[2], NULL, 0);
99		    codes [1] = (unsigned) value;
100
101		    if(ioctl(fd, EVIOCSKEYCODE, codes))
102			    perror ("EVIOCSKEYCODE");
103
104		    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
105			    prtcode(codes);
106		    return 0;
107	    }
108
109	    if (argc==3) {
110		    FILE *fin;
111		    int value;
112		    char *scancode, *keycode, s[2048];
113
114		    fin=fopen(argv[2],"r");
115		    if (fin==NULL) {
116			    perror ("opening keycode file");
117			    return -1;
118		    }
119
120		    /* Clears old table */
121		    for (j = 0; j < 256; j++) {
122			    for (i = 0; i < 256; i++) {
123				    codes[0] = (j << 8) | i;
124				    codes[1] = KEY_RESERVED;
125				    ioctl(fd, EVIOCSKEYCODE, codes);
126			    }
127		    }
128
129		    while (fgets(s,sizeof(s),fin)) {
130			    scancode=strtok(s,"\\n\\t =:");
131			    if (!scancode) {
132				    perror ("parsing input file scancode");
133				    return -1;
134			    }
135			    if (!strcasecmp(scancode, "scancode")) {
136				    scancode = strtok(NULL,"\\n\\t =:");
137				    if (!scancode) {
138					    perror ("parsing input file scancode");
139					    return -1;
140				    }
141			    }
142
143			    keycode=strtok(NULL,"\\n\\t =:(");
144			    if (!keycode) {
145				    perror ("parsing input file keycode");
146				    return -1;
147			    }
148
149			    // printf ("parsing %s=%s:", scancode, keycode);
150			    value=parse_code(keycode);
151			    // printf ("\\tvalue=%d\\n",value);
152
153			    if (value==-1) {
154				    value = strtol(keycode, NULL, 0);
155				    if (errno)
156					    perror("value");
157			    }
158
159			    codes [0] = (unsigned) strtol(scancode, NULL, 0);
160			    codes [1] = (unsigned) value;
161
162			    // printf("\\t%04x=%04x\\n",codes[0], codes[1]);
163			    if(ioctl(fd, EVIOCSKEYCODE, codes)) {
164				    fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
165				    perror ("EVIOCSKEYCODE");
166			    }
167
168			    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
169				    prtcode(codes);
170		    }
171		    return 0;
172	    }
173
174	    /* Get scancode table */
175	    for (j = 0; j < 256; j++) {
176		    for (i = 0; i < 256; i++) {
177			    codes[0] = (j << 8) | i;
178			    if (!ioctl(fd, EVIOCGKEYCODE, codes) && codes[1] != KEY_RESERVED)
179				    prtcode(codes);
180		    }
181	    }
182	    return 0;
183    }
184