Question

All my code was based upon an article from linuxjournal.com here is the article I based my code on

I'm writing an embedded app, and I'm trying to read the keystrokes from a keyboard.
Here is the code I'm using

uint8_t key_b[KEY_MAX/8 + 1];
memset(key_b, 0, sizeof(key_b));
ioctl(fd, EVIOCGKEY(sizeof(key_b)), key_b);

for (yalv = 0; yalv < KEY_MAX; yalv++) {
    if (test_bit(yalv, key_b)) {
        /* the bit is set in the key state */
        printf("  Key 0x%02x ", yalv);
        switch ( yalv)
        {
        case KEY_RESERVED :
            printf(" (Reserved)\n");
            break;
        case KEY_ESC :
            printf(" (Escape)\n");
            break;
        /* other keys / buttons not shown */
        case BTN_STYLUS2 :
            printf(" (2nd Stylus Button )\n");
            break;
        case KEY_1:
            printf("The key 1 was pressed");
            break;
        case KEY_2:
            printf("The key 2 was pressed");
            break;
        case KEY_A:
            printf("The key A was pressed");
            break;
        default:
            printf(" (Unknown key)\n");
        }
    }
}

For the most part this code works, EXCEPT when I press 'a'.

According to the input.h KEY_A is set to be the value 30. But when I press 'a' on the keyboard, it returns the value 102 instead of 30. I've tested the other keys on the keyboard, and it seems like the keys 1-6 return the expected value of KEY_1, KEY_2 and etc., but after that the values returned aren't right.

I've tried reading the even directly from the /dev/input/eventX file. And the code returned in the events are expected.

size_t rb;
/* the events (up to 64 at once) */
struct input_event ev[64];
int yalv;
int keybrdToCapture;

    if((keybrdToCapture = open(EVENT2, O_RDONLY)) == -1) {
    perror("opening device");
    exit(EXIT_FAILURE);
    printf("L2\n");
}

rb=read(keybrdToCapture,ev,sizeof(struct input_event)*64);

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

The above code gives this print out when I hit the 'a' key. type 1 code 30 value 1

At this point you might wonder why I don't simply read the input event to read the keyboard input. This is because read() is a blocking function. While ioctl() is not blocking.

If anyone could please help me figure out why EVIOCGKEY() is returning the incorrect key values, I'd be very grateful. Thanks!

Était-ce utile?

La solution

Ok, I figured out what the problem was.

my test_bit() macro was written incorrectly.
Basically, key_b[] represents the state of the keys, bit by bit. Meaning if KEY_A is pressed, then bit 30 will be set to 1. In this case, bit 30 will show up in key_b[3] as the value 0x40.

Here's a few more examples of how each key will map into key_b[].

  • KEY_1 = 2 represented in key_b as --> key_b[0] = 0x04;
  • KEY_2 = 3 represented in key_b as --> key_b[0] = 0x08;
  • KEY_3 = 4 represented in key_b as --> key_b[0] = 0x10;
  • KEY_4 = 5 represented in key_b as --> key_b[0] = 0x20;
  • KEY_5 = 6 represented in key_b as --> key_b[0] = 0x40;
  • KEY_6 = 7 represented in key_b as --> key_b[0] = 0x80;
  • KEY_7 = 8 represented in key_b as --> key_b[1] = 0x01;
  • KEY_8 = 9 represented in key_b as --> key_b[1] = 0x02;
  • KEY_9 = 10 represented in key_b as --> key_b[2] = 0x04;
  • KEY_0 = 11 represented in key_b as --> key_b[3] = 0x08;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top