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!

Was it helpful?

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top