Arthur Rodrigues
Arthur Rodrigues

Reputation: 11

How does 4 byte scancode get mapped to keycodes in Linux?

I was messing around with scancodes and keycodes in Debian Buster and I've found something strange.

Using sudo showkey -s I discovered that the scancode of the PrintScreen/SysRq key of my USB wired keyboard is

0xe0 0x2a 0xe0 0x37 0xe0 0xaa 0xe0 0xb7,

that is, 0xe0 0x2a 0xe0 0x37 is the code for pressing it and 0xe0 0xaa 0xe0 0xb7 for releasing it.

My first question is: Why is it using two scancodes (0xe0 0x2a and 0xe0 0x37)? Coundn't this conflict with others scancodes? Wouldn't be smarter to use an unused scancode?

Using sudo showkey -k I discovered that PrintScreen/SysRq is associated with the kernel keycode 99, but when I run sudo getkeycodes, there isn't an entry for the X keycode 107.

The output of sudo getkeycodes is

Códigos de varredura planos xx (hex) versus códigos de teclas (dec)
0 é um erro; para 1-88 (001-0x58) código de varredura igual a código de tecla

 0x58:   88   -   -   - 185 238   -   -
 0x60:    -   -   -   -   -   -   -   -
 0x68:    -   -   - 191   -   -   -   -
 0x70:    -   -   -   -   -   -   -   -
 0x78:    -   -   -   -   -   -   -   -

Códigos de varredura escapados e0 xx (hex)

e0 00:    -   - 212 533   -   -   -   -
e0 08:  238   -   -   -   -   -   -   -
e0 10:    -   -   -   -   -   -   -   -
e0 18:    -   -   -   -   -   -   -   -
e0 20:    -   -   -   -   -   -   -   -
e0 28:    -   -   -   -   -   -   -   -
e0 30:    -   -   -   -   -   -   -   -
e0 38:    -   -   -   -   - 212   -   -
e0 40:    -   -   -   -   -   -   -   -
e0 48:    -   -   -   - 227   -   -   -
e0 50:    -   -   -   -   -   -   -   -
e0 58:    -   -   -   -   -   -   -   -
e0 60:  148 184   -   - 171   -   -   -
e0 68:  152 431   - 534 535 536 537 538
e0 70:    -   -   - 139   - 172   1   -
e0 78:    -   -   -   -   -   -   -   -

My second question is: If there isn't a entry in the above output, how does the mapping of PrintScreen/SysRq from scancode to keycode works?

If necessary, I can provide any additional info.

Thank you all in advance.

EDIT 1: I realized that this combination of scancodes conflicts with pressing Shift+ (Ctrl-PrtScn), I confirmed that Shift's scancode is 0x2a 0xaa by running sudo showkey -s and I found (Ctrl-PrtScn)'s code in this documentation.

I've searched /usr/lib/udev/hwdb.d/60-keyboard.hwdb for this map, but didn't find anything.

Upvotes: 1

Views: 877

Answers (1)

SergiyKolesnikov
SergiyKolesnikov

Reputation: 7815

The documentation that you posted in your edit actually provides answers to most of your questions.

Can the PrtSc scancode be confused with sequences produced by other keypresses?

PrtSc is one of the two keys that produce multiple scancodes. The other one is Pause/Break (see Sec. 1.1 in [1]). A keyboard driver parsing a stream of scancodes would know that some keys produce several scancodes. So, if needed it would wait for several scancodes to arrive and then would match them against known combinations.

There is an alternative set of scancodes, Set 3 (see [2]), that uses unique scancodes for each key and therefore simplifies parsing of a scancode stream. But it did not gain acceptance.

Why is there no entry for PrtSc in my output of getkeycodes?

Maybe you played around with setkeycodes and removed it?

Notice, getkeycodes shows kernel keycodes and not X keycodes (that equal kernel kyecode + 8, as you correctly noted). So, you should look for 99 and not 107.

The X keycodes can be looked up in, for example, /usr/share/X11/xkb/keycodes/evdev

Alleged conflict of scancodes for PrtSc and Shift+Ctrl+PrtSc

PrtSc is also special in the way that it produces different scancodes depending on with which modifier keys it is pressed (see Sec. 1.1 in [1]):

  • PrtSc produces e0 2a e0 37
  • PrtSc together with Shift or Ctrl produces e0 37
  • PrtSc together with Alt produces 54

I believe this prevents the conflict as you described it.

Upvotes: 0

Related Questions