Winston
Winston

Reputation: 111

KDGKBENT returns wrong keysym values?

Example code:

#include <stdio.h>
#include <stdlib.h>
#include <linux/keyboard.h>
#include <sys/ioctl.h>
#include <sys/kd.h>

int
main(int argc, char **argv) {
  struct kbentry ke;
  
  ke.kb_table = (unsigned char)atoi(argv[1]);
  ke.kb_index = (unsigned char)atoi(argv[2]);
  ioclt(0, KDGKBENT, &ke);
  printf("keycode %u = %04x\n", ke.kb_index, ke.kb_value);
  return 0;
}

When I try to get the value of a keycode using e.g. the code above, KDGKBENT returns strange values. It adds a '0B' to ASCII characters: 0x0B61 for 'a' instead of 0x0061, 0x0B41 for 'A' instead of 0x0041.

I cannot find any answer regarding to what this happens on the internet.

I only found the same question, without any answer there: https://www.unix.com/unix-for-advanced-and-expert-users/178627-questions-about-linux-console-keyboard-driver-translation-tables.html

Those values in 0x0Bxx do not appear when running dumpkeys -l (alphabet has normal ASCII values), nor in this list: https://wiki.linuxquestions.org/wiki/List_of_keysyms

Why does this happen? And how am I supposed to get a proper conversion?

Actually, looking carefully at dumpkeys tables, the alphabet keys symbols are '+a', '+A' etc. i.e. they are Caps Lock conditioned to change their case. Could be the explanation behind '0x0B' but I need to find a confirmation about this theory.

Upvotes: 1

Views: 104

Answers (1)

Stas Badzi
Stas Badzi

Reputation: 748

I also had this problem, so I decided to check why dumpkeys work but my code doesn't and while looking through the source code I found this fragment of code (src/libkeymap/keysyms.c:195):

if (KTYP(code) == KT_LETTER)
      code = K(KT_LATIN, KVAL(code));

where code is the ke.kb_value from

struct kbentry ke;
ke.kb_table = 0; // no modifiers
ke.kb_index = 16; // q in en-us layout
ke.kb_value = 0;

ioctl(fd, KDGKBENT, (unsigned long)&ke);

It checks for letter keys and converts them to their latin version (by changing the KTYP from KT_LETTER to KT_LATIN).

It solved the issue for me

Upvotes: 0

Related Questions