
// https://stackoverflow.com/questions/30994628/why-does-xgrabkey-return-badrequest

{$MODE OBJFPC}
{$H+}
{$RANGECHECKS ON}

uses
xlib,
 xutil,
keysym,
xfixes,
x;

var
d :  PXDisplay;
root : TWindow;
keycode, rv : Int64;
m : DWord;
evt : TXEvent;

//     #define ShiftMapIndex	 0
//     #define LockMapIndex	 1
//     #define ControlMapIndex	 2
//     #define Mod1MapIndex	 3
//     #define Mod2MapIndex	 4
//     #define Mod3MapIndex	 5
//     #define Mod4MapIndex	 6
//     #define Mod5MapIndex	 7
//static const struct {
//	const char* name;
//	unsigned int mask;
//} xmodifiers[] = {
//	[ShiftMapIndex]   = { "shift",    ShiftMask,   },
//	[LockMapIndex]    = { "lock",     LockMask,    },
//	[ControlMapIndex] = { "control",  ControlMask, },
//	[Mod1MapIndex]    = { "mod1",     Mod1Mask,    },
//	[Mod2MapIndex]    = { "mod2",     Mod2Mask,    },
//	[Mod3MapIndex]    = { "mod3",     Mod3Mask,    },
//	[Mod4MapIndex]    = { "mod4",     Mod4Mask,    },
//	[Mod5MapIndex]    = { "mod5",     Mod5Mask,    },
//};
xmodifiers : array[0..7] of DWord = (ShiftMask,LockMask,ControlMask,Mod1Mask,Mod2Mask,Mod3Mask,Mod4Mask,Mod5Mask);

function get_mod_mask(modsym : TKeySym) : DWord;
var
	i : integer;
	modmask : dword = 0;
	nlkc : TKeyCode;
	modmap : PXModifierKeymap;
begin
	nlkc := XKeysymToKeycode(d, modsym);
	modmap := XGetModifierMapping(d);
	for i := 0 to 8 * modmap^.max_keypermod - 1 do begin
		if (modmap^.modifiermap[i] = nlkc)  then begin
			modmask := xmodifiers[i div modmap^.max_keypermod];
			break;
		end;
	end;
	XFreeModifiermap(modmap);
	Exit(modmask);
end;

begin
d := XOpenDisplay(nil);
root := DefaultRootWindow(d);
keycode := XKeysymToKeycode(d, XK_F12);
//m := get_mod_mask(XK_Shift_L);
m := ControlMask + ShiftMask;

writeln('KeyCode: ', keycode);

rv := XGrabKey(d, keycode , {AnyModifier} m, root, 1, GrabModeAsync, GrabModeAsync);
writeln('XGrabKey returned');
writeln(rv);

    while true do begin
        XNextEvent(d, @evt);
        writeln('Got event');
        writeln(evt._type);
case evt._type of
KeyPress:
WriteLn('>>> ',evt.xkey.keycode);
end;
    end;
end.