In an application that runs in a frame buffer, I read keys from /dev/tty after having set it to mediumraw mode using

int fd = open("/dev/tty", O_RDWR);

In order to get at the unicode values of the keys representing chars, I do something along the lines of

struct kbentry entry;
entry.kb_table = (some combination of KG_* values or 0);
entry.kb_index = code & 0x7f; /* code is the value received by read()ing from /dev/tty */
ioctl(kbd->fd, KDGKBENT, &entry);
/* unicode value is now in entry.kb_value */

This works quite well, except for one thing: when my keyboard has dead chars, I get those returned as 0x0400, 0x0401, 0x0402 etc. The 0x04 is KT_DEAD, so this looks about right, but when I read the kernel's diacritical table into a struct kbdiacrsuc, I see that that expects actual character codes instead of 01, 02, ... So, how do I get those character codes from the dead keys?


Answering my own question here, as I've figured it out. Studying /usr/include/linux/keyboard.h revealed that there may ony be 6 of those dead characters to take into account. After looking at what's in the struct kbdiacrsuc, I came up with this:

    switch (entry.kb_value) {
            case K_DGRAVE: accent = 96; break;
            case K_DACUTE: accent = 39; break;
            case K_DCIRCM: accent = 94; break;
            case K_DTILDE: accent = 126; break;
            case K_DDIERE: accent = 34; break;
            case K_DCEDIL: accent = 44; break;
            default: /* whatever... */

Then, doing a lookup with one of these as diacr and another char as base yields the desired accented character.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.