162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later
262306a36Sopenharmony_ci
362306a36Sopenharmony_cifile: uapi/v4l/keytable.c
462306a36Sopenharmony_ci=========================
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci.. code-block:: c
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci    /* keytable.c - This program allows checking/replacing keys at IR
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci       Copyright (C) 2006-2009 Mauro Carvalho Chehab <mchehab@kernel.org>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci       This program is free software; you can redistribute it and/or modify
1362306a36Sopenharmony_ci       it under the terms of the GNU General Public License as published by
1462306a36Sopenharmony_ci       the Free Software Foundation, version 2 of the License.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci       This program is distributed in the hope that it will be useful,
1762306a36Sopenharmony_ci       but WITHOUT ANY WARRANTY; without even the implied warranty of
1862306a36Sopenharmony_ci       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1962306a36Sopenharmony_ci       GNU General Public License for more details.
2062306a36Sopenharmony_ci     */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci    #include <ctype.h>
2362306a36Sopenharmony_ci    #include <errno.h>
2462306a36Sopenharmony_ci    #include <fcntl.h>
2562306a36Sopenharmony_ci    #include <stdio.h>
2662306a36Sopenharmony_ci    #include <stdlib.h>
2762306a36Sopenharmony_ci    #include <string.h>
2862306a36Sopenharmony_ci    #include <linux/input.h>
2962306a36Sopenharmony_ci    #include <sys/ioctl.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci    #include "parse.h"
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci    void prtcode (int *codes)
3462306a36Sopenharmony_ci    {
3562306a36Sopenharmony_ci	    struct parse_key *p;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	    for (p=keynames;p->name!=NULL;p++) {
3862306a36Sopenharmony_ci		    if (p->value == (unsigned)codes[1]) {
3962306a36Sopenharmony_ci			    printf("scancode 0x%04x = %s (0x%02x)\\n", codes[0], p->name, codes[1]);
4062306a36Sopenharmony_ci			    return;
4162306a36Sopenharmony_ci		    }
4262306a36Sopenharmony_ci	    }
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	    if (isprint (codes[1]))
4562306a36Sopenharmony_ci		    printf("scancode %d = '%c' (0x%02x)\\n", codes[0], codes[1], codes[1]);
4662306a36Sopenharmony_ci	    else
4762306a36Sopenharmony_ci		    printf("scancode %d = 0x%02x\\n", codes[0], codes[1]);
4862306a36Sopenharmony_ci    }
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci    int parse_code(char *string)
5162306a36Sopenharmony_ci    {
5262306a36Sopenharmony_ci	    struct parse_key *p;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	    for (p=keynames;p->name!=NULL;p++) {
5562306a36Sopenharmony_ci		    if (!strcasecmp(p->name, string)) {
5662306a36Sopenharmony_ci			    return p->value;
5762306a36Sopenharmony_ci		    }
5862306a36Sopenharmony_ci	    }
5962306a36Sopenharmony_ci	    return -1;
6062306a36Sopenharmony_ci    }
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci    int main (int argc, char *argv[])
6362306a36Sopenharmony_ci    {
6462306a36Sopenharmony_ci	    int fd;
6562306a36Sopenharmony_ci	    unsigned int i, j;
6662306a36Sopenharmony_ci	    int codes[2];
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	    if (argc<2 || argc>4) {
6962306a36Sopenharmony_ci		    printf ("usage: %s <device> to get table; or\\n"
7062306a36Sopenharmony_ci			    "       %s <device> <scancode> <keycode>\\n"
7162306a36Sopenharmony_ci			    "       %s <device> <keycode_file>n",*argv,*argv,*argv);
7262306a36Sopenharmony_ci		    return -1;
7362306a36Sopenharmony_ci	    }
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	    if ((fd = open(argv[1], O_RDONLY)) < 0) {
7662306a36Sopenharmony_ci		    perror("Couldn't open input device");
7762306a36Sopenharmony_ci		    return(-1);
7862306a36Sopenharmony_ci	    }
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	    if (argc==4) {
8162306a36Sopenharmony_ci		    int value;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci		    value=parse_code(argv[3]);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci		    if (value==-1) {
8662306a36Sopenharmony_ci			    value = strtol(argv[3], NULL, 0);
8762306a36Sopenharmony_ci			    if (errno)
8862306a36Sopenharmony_ci				    perror("value");
8962306a36Sopenharmony_ci		    }
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci		    codes [0] = (unsigned) strtol(argv[2], NULL, 0);
9262306a36Sopenharmony_ci		    codes [1] = (unsigned) value;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci		    if(ioctl(fd, EVIOCSKEYCODE, codes))
9562306a36Sopenharmony_ci			    perror ("EVIOCSKEYCODE");
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci		    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
9862306a36Sopenharmony_ci			    prtcode(codes);
9962306a36Sopenharmony_ci		    return 0;
10062306a36Sopenharmony_ci	    }
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	    if (argc==3) {
10362306a36Sopenharmony_ci		    FILE *fin;
10462306a36Sopenharmony_ci		    int value;
10562306a36Sopenharmony_ci		    char *scancode, *keycode, s[2048];
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci		    fin=fopen(argv[2],"r");
10862306a36Sopenharmony_ci		    if (fin==NULL) {
10962306a36Sopenharmony_ci			    perror ("opening keycode file");
11062306a36Sopenharmony_ci			    return -1;
11162306a36Sopenharmony_ci		    }
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci		    /* Clears old table */
11462306a36Sopenharmony_ci		    for (j = 0; j < 256; j++) {
11562306a36Sopenharmony_ci			    for (i = 0; i < 256; i++) {
11662306a36Sopenharmony_ci				    codes[0] = (j << 8) | i;
11762306a36Sopenharmony_ci				    codes[1] = KEY_RESERVED;
11862306a36Sopenharmony_ci				    ioctl(fd, EVIOCSKEYCODE, codes);
11962306a36Sopenharmony_ci			    }
12062306a36Sopenharmony_ci		    }
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci		    while (fgets(s,sizeof(s),fin)) {
12362306a36Sopenharmony_ci			    scancode=strtok(s,"\\n\\t =:");
12462306a36Sopenharmony_ci			    if (!scancode) {
12562306a36Sopenharmony_ci				    perror ("parsing input file scancode");
12662306a36Sopenharmony_ci				    return -1;
12762306a36Sopenharmony_ci			    }
12862306a36Sopenharmony_ci			    if (!strcasecmp(scancode, "scancode")) {
12962306a36Sopenharmony_ci				    scancode = strtok(NULL,"\\n\\t =:");
13062306a36Sopenharmony_ci				    if (!scancode) {
13162306a36Sopenharmony_ci					    perror ("parsing input file scancode");
13262306a36Sopenharmony_ci					    return -1;
13362306a36Sopenharmony_ci				    }
13462306a36Sopenharmony_ci			    }
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci			    keycode=strtok(NULL,"\\n\\t =:(");
13762306a36Sopenharmony_ci			    if (!keycode) {
13862306a36Sopenharmony_ci				    perror ("parsing input file keycode");
13962306a36Sopenharmony_ci				    return -1;
14062306a36Sopenharmony_ci			    }
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci			    // printf ("parsing %s=%s:", scancode, keycode);
14362306a36Sopenharmony_ci			    value=parse_code(keycode);
14462306a36Sopenharmony_ci			    // printf ("\\tvalue=%d\\n",value);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci			    if (value==-1) {
14762306a36Sopenharmony_ci				    value = strtol(keycode, NULL, 0);
14862306a36Sopenharmony_ci				    if (errno)
14962306a36Sopenharmony_ci					    perror("value");
15062306a36Sopenharmony_ci			    }
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci			    codes [0] = (unsigned) strtol(scancode, NULL, 0);
15362306a36Sopenharmony_ci			    codes [1] = (unsigned) value;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci			    // printf("\\t%04x=%04x\\n",codes[0], codes[1]);
15662306a36Sopenharmony_ci			    if(ioctl(fd, EVIOCSKEYCODE, codes)) {
15762306a36Sopenharmony_ci				    fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
15862306a36Sopenharmony_ci				    perror ("EVIOCSKEYCODE");
15962306a36Sopenharmony_ci			    }
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci			    if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
16262306a36Sopenharmony_ci				    prtcode(codes);
16362306a36Sopenharmony_ci		    }
16462306a36Sopenharmony_ci		    return 0;
16562306a36Sopenharmony_ci	    }
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	    /* Get scancode table */
16862306a36Sopenharmony_ci	    for (j = 0; j < 256; j++) {
16962306a36Sopenharmony_ci		    for (i = 0; i < 256; i++) {
17062306a36Sopenharmony_ci			    codes[0] = (j << 8) | i;
17162306a36Sopenharmony_ci			    if (!ioctl(fd, EVIOCGKEYCODE, codes) && codes[1] != KEY_RESERVED)
17262306a36Sopenharmony_ci				    prtcode(codes);
17362306a36Sopenharmony_ci		    }
17462306a36Sopenharmony_ci	    }
17562306a36Sopenharmony_ci	    return 0;
17662306a36Sopenharmony_ci    }
177