Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xcb keyboard button masks meaning

Tags:

x11

xcb

I'm trying to figure what keys are handled by:

  • XCB_MOD_MASK_1
  • XCB_MOD_MASK_2
  • XCB_MOD_MASK_3
  • XCB_MOD_MASK_4
  • XCB_MOD_MASK_5

in xcb, for XCB_MOD_MASK_1 it seems to be Alt (i'm correct?), but for others button i cannot find the mapping anywhere (i tried to google them before posting, but with no success).

So what are the usual key associated to these masks?

like image 246
Ivan Avatar asked Oct 15 '13 08:10

Ivan


2 Answers

Usually Mask1 is Alt or Meta, Mask2 is Num lock, Mask3 is AltGr, Mask4 is Win, and Mask5 is Scroll lock, but this varies between X implementations and/or keyboard models.

Source: my own computer running X11, and various bits and pieces of code lying around on the 'net. Not all of them are consistent, e.g. some say Mod1 is Alt and Mod4 is Meta.

X11 programs normally let users configure actions corresponding to Mask1 ... Mask5, and have them sort out which key sets which mask.

like image 102
n. 1.8e9-where's-my-share m. Avatar answered Oct 30 '22 01:10

n. 1.8e9-where's-my-share m.


You can actually configure what those keys (or any keys) are mapped to, with a utility like xmodmap. In the X Window System there are eight modifiers. The 8 modifiers are

  1. shift
  2. lock
  3. control
  4. mod1
  5. mod2
  6. mod3
  7. mod4
  8. mod5

To see what keys are currently mapped to these modifiers you can run xmodmap -pm, which prints the modifier map. Eg. for me the output is

xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):

shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)

So Alt generates mod1, for instance.

Now to change mod1 through mod5 with xmodmap, open ~/.Xmodmap and write something like:

clear mod1
clear mod2
clear mod3
clear mod4
clear mod5

add mod1 = Alt_L Alt_R Meta_L
add mod2 = Num_Lock
add mod3 = ISO_Level3_Shift
add mod4 = Super_L Super_R Super_L Hyper_L
add mod5 = ISO_Level5_Shift

Then run xmodmap ~/.Xmodmap.

And now, for instance, ISO_Level3_Shift is what gives you mod3.

How you can actually get a key from your keyboard to generate the keycode that corresponds to ISO_Level3_Shift is another challenge.

Eg. to get keycode 100 to generate ISO_Level3_Shift (which is now mod3), add the following to your ~/.Xmodmap file and run xmodmap ~/.Xmodmap.

keycode 100 = ISO_Level3_Shift

The keycode with, for instance, value 100 should be generated by udev. When you press a physical key in your keyboard, the microcontroller/firmware maps that physical key to a scancode and sends that scancode through the USB interface. Then udev maps that scancode to a Linux kernel keycode. Then X11 maps that kernel keycode to an X11 keycode. And then X11 maps that X11 keycode to an X11 keysym. Needless to say, this mapping is unnecessarily complicated. (In particular, I almost always ignore X11 keysyms and work with raw X11 keycodes.)

You might hear that xmodmap is deprecated, and that you should mess with XKB config files and stuff, but using XKB is much, much, much worse.

(Keyboards are really simple (just a circuit+microcontroller that scans the physical key matrix, keyboard-side firmware that knows USB HID, and then a kernel-side driver that maps firmware-dependent scancodes to standardized keycodes), but people have made them really complicated. Also, scancodes/keycodes should've been 32-bit from the start.)


In the X protocol, the 8 modifiers (shift, ..., mod1, ..., mod5) have a bitmask associated to them. This is the bitmask that XCB implements using a C enum, and its precise values are:

enum xcb_mod_mask_t{
  XCB_MOD_MASK_SHIFT                    = 1<<0,
  XCB_MOD_MASK_LOCK                     = 1<<1,
  XCB_MOD_MASK_CONTROL                  = 1<<2,
  XCB_MOD_MASK_1                        = 1<<3,
  XCB_MOD_MASK_2                        = 1<<4,
  XCB_MOD_MASK_3                        = 1<<5,
  XCB_MOD_MASK_4                        = 1<<6,
  XCB_MOD_MASK_5                        = 1<<7,
  XCB_MOD_MASK_ANY                      = 1<<15,
};

These values aren't XCB's choice, but they're prescribed by the X protocol specification and you can use them when talking to the X server through the X protocol. Eg. when the X server sends you an XCB_KEY_PRESS event, this event is a 32-byte struct, and one of its fields is a bitmask where the bits are set according to the modifiers that were pressed during that key press event. Eg. if bit 0 is set, it means XCB_MOD_MASK_SHIFT is set, meaning the Shift modifier was help down.

like image 33
étale-cohomology Avatar answered Oct 30 '22 01:10

étale-cohomology