¿Cómo puedo traducir códigos de teclas de Linux / dev / input / * evento a ASCII en Perl?

StackOverflow https://stackoverflow.com/questions/2547616

  •  23-09-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un script en Perl que lee los datos de la infame /dev/input/event* y no encontré una manera de traducir los códigos claves generadas por el núcleo en ASCII.

Estoy hablando de los códigos de teclas linux en esta tabla aquí y me parece que no puede encontrar algo que me ayude a traducir sin codificar una matriz en la secuencia de comandos. ¿Me estoy perdiendo de algo?

Me gustaría omitir la parte de matriz, ya que no parece ser una práctica buena, por lo que cualquier idea? :)

¿Fue útil?

Solución

Se trata básicamente de un problema mapa. Usted tiene que tomar un código clave y la búsqueda de su equivalente ASCII. ¿Qué pasa con la "parte array" ¿cree usted que no es una buena práctica?

No he visto un módulo para este en CPAN, pero eso significa que usted tiene la oportunidad de ser el primero en subirlo. :)

Otros consejos

Por desgracia, no lo hago programa en Perl, pero aquí está un ejemplo sencillo escrito en C. Tal vez podría ayudarle, sin embargo.

/*
 * Based on keytable.c by Mauro Carvalho Chehab
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#include <linux/input.h>

#include <string.h>
#include <linux/input.h>
#include <sys/ioctl.h>

#define KEY_RELEASE 0
#define KEY_PRESS 1
#define KEY_KEEPING_PRESSED 2

#include "parse.h"

void prtcode(int codes) {
    struct parse_key *p;

    for (p = keynames; p->name != NULL; p++) {
        if (p->value == (unsigned) codes) {
            printf("scancode %s (0x%02x)\n", p->name, codes);
            return;
        }
    }

    if (isprint(codes)) {
        printf("scancode '%c' (0x%02x)\n", codes, codes);
    } else {
        printf("scancode 0x%02x\n", codes);
    }
}

int main (int argc, char *argv[]) {
    int i, fd;
    struct input_event ev[64];

    if (argc != 2) {
        fprintf(stderr, "usage: %s event-device (/dev/input/eventX)\n", argv[0]);
        return 1;
    }

    if ((fd = open(argv[1], O_RDONLY)) < 0) {
        perror("Couldn't open input device");
        return 1;
    }

    while (1) {
        size_t rb = read(fd, ev, sizeof(ev));

        if (rb < (int) sizeof(struct input_event)) {
            perror("short read");
            return 1;
        }

        for (i = 0; i < (int) (rb / sizeof(struct input_event)); i++) {
            if (EV_KEY == ev[i].type) {
                if ((ev[i].value == KEY_PRESS) || (ev[i].value == KEY_KEEPING_PRESSED)) {
                    prtcode(ev[i].code);
                    printf("type %d code %d value %d\n", ev[i].type, ev[i].code, ev[i].value);
                    printf("\n");
                }
            }
        }
    }

    return 0;
}

Para generar el parse.h, poner esto en su Makefile:

parse.h: /usr/include/linux/input.h
    @echo generating parse.h
    @echo -en "struct parse_key {\n\tchar *name;\n\tunsigned int value;\n} " >parse.h
    @echo -en "keynames[] = {\n" >>parse.h

    @more /usr/include/linux/input.h |perl -n \
    -e 'if (m/^\#define\s+(KEY_[^\s]+)\s+(0x[\d\w]+|[\d]+)/) ' \
    -e '{ printf "\t{\"%s\", %s},\n",$$1,$$2; }' \
    -e 'if (m/^\#define\s+(BTN_[^\s]+)\s+(0x[\d\w]+|[\d]+)/) ' \
    -e '{ printf "\t{\"%s\", %s},\n",$$1,$$2; }' \
    >> parse.h
    @echo -en "\t{ NULL, 0}\n};\n" >>parse.h

A continuación, utilizar de esta manera:

./keytable /dev/input/by-path/platform-i8042-serio-0-event-kbd

Ejemplo 1 solo le da una copia de los mismos valores de código clave que ya están llegando desde el núcleo de Linux. Por ejemplo, usted get KEY_A 0x1E por una 'a' pulsación de tecla. Lo que queremos es (y lo que quiero) es la conversión ASCII por lo que si se presiona 'a' Quiero ver 0x61 para minúsculas y 0x41 para mayúsculas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top