Update Xkb records and their types and remove excessive whitespacing
Older Xkb definitions were resulting in misalignments and gibberish data. Updated types (Boolean to TBool, some unsigned shorts were Bytes, instead of Word, some unsigned int were Word, instead of LongWord etc etc).
C++ test. Portion mostly taken from Xdo-tool.
#include <iostream>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
int main() {
Display *xdpy;
int keycode, group, groups, level, modmask, num_map;
int keycode_low, keycode_high, keysyms_per_keycode;
xdpy = XOpenDisplay(XDisplayName(NULL));
XDisplayKeycodes(xdpy, &(keycode_low), &(keycode_high));
KeySym *keysyms = XGetKeyboardMapping(xdpy, keycode_low,
keycode_high - keycode_low + 1,
&keysyms_per_keycode);
XFree(keysyms);
XkbDescPtr desc = XkbGetMap(xdpy, XkbAllClientInfoMask, XkbUseCoreKbd);
for (keycode = keycode_low; keycode <= keycode_high; keycode++) {
groups = XkbKeyNumGroups(desc, keycode);
if (keycode == 17)
std::cout << "Keycode=" << keycode << ", Groups=" << groups << std::endl;
for (group = 0; group < groups; group++) {
XkbKeyTypePtr key_type = XkbKeyKeyType(desc, keycode, group);
int levels = key_type->num_levels;
if (keycode == 17)
std::cout << "Keycode=" << keycode << ", Group=" << group << ", Levels=" << levels << std::endl;
for (level = 0; level < levels; level++) {
KeySym keysym = XkbKeycodeToKeysym(xdpy, keycode, group, level);
if (keycode == 17 && keysym != 0) {
modmask = 0;
for (num_map = 0; num_map < key_type->map_count; num_map++) {
XkbKTMapEntryRec map = key_type->map[num_map];
if (/*map.active &&*/ map.level == level) {
modmask = map.mods.mask;
break;
}
}
std::cout << "Keycode=" << keycode << ", KeySym=" << std::hex << std::uppercase << keysym << std::dec << ", Group=" << group << ", Level=" << level << ", Mask=" << modmask << std::endl;
}
}
}
}
XkbFreeKeyboard(desc, 0, 1);
}
Compile with
cc -g -O2 xkbtest.cpp -o xkbtest -lX11 -lstdc++
Pascal test
program fpxkbtest;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
Classes, SysUtils, Unix, x, xlib, XKB, xkblib
{ you can add units after this };
var
LXDisplay: PDisplay;
pDesc: PXkbDescPtr;
pKeySyms: PKeySym;
iKeycodeLow, iKeycodeHigh, iKeySymsPerKeycode: cint;
btKeycode: TKeyCode;
btGroup, btGroups, btLevel, btLevels, btMap, btMask: Byte;
wXkbKeySym: TKeySym;
pXkbKeyType: PXkbKeyTypePtr;
pMap: PXkbKTMapEntryPtr;
begin
LXDisplay := XOpenDisplay(nil);
XDisplayKeycodes(LXDisplay, @iKeycodeLow, @iKeycodeHigh);
pKeySyms := XGetKeyboardMapping(LXDisplay, iKeycodeLow, iKeycodeHigh - iKeycodeLow + 1, @iKeySymsPerKeycode);
XFree(pKeySyms);
pDesc := XkbGetMap(LXDisplay, XkbAllClientInfoMask, XkbUseCoreKbd);
try
for btKeycode := iKeycodeLow to iKeycodeHigh do
begin
btGroups := XkbKeyNumGroups(pDesc, btKeycode);
if (btKeycode = 17) then
WriteLn('Keycode=', btKeycode, ', Groups=', btGroups);
for btGroup := 0 to btGroups-1 do
begin
pXkbKeyType := XkbKeyKeyType(pDesc, btKeycode, btGroup);
btLevels := pXkbKeyType^.num_levels;
if (btKeycode = 17) then
WriteLn('Keycode=', btKeycode, ', Group=', btGroup, ', Levels=', btLevels);
for btLevel:=0 to btLevels-1 do
begin
wXkbKeySym := XkbKeycodeToKeysym(LXDisplay, btKeycode, btGroup, btLevel);
if (btKeycode = 17) and (wXkbKeySym <> 0) then
begin
btMask := 0;
for btMap:=0 to pXkbKeyType^.map_count-1 do
begin
// crashing due to active being Boolean
//try
pMap := PXkbKTMapEntryPtr(@(pXkbKeyType^.map[btMap]));
if {(pXkbKeyType^.map[btMap].active) and} (pMap^.level = btLevel) then
begin
btMask := pMap^.mods.mask;
Break;
end;
//except
//end;
end;
WriteLn('Keycode=', btKeycode, ', KeySym=', IntToHex(wXkbKeySym, 4), ', Group=', btGroup, ', Level=', btLevel, ', Mask=', btMask);
end;
end;
end;
end;
finally
XkbFreeKeyboard(pDesc, 0, True);
end;
end.
The test is testing Keycode 17, as 8 button is only button with AltGr use in Russian layout. As AltGr generally not mapped to every key. 17 can be changed to another key to reflect other layouts.