program c;

{
/**
 * Launch a terminal when Ctrl-Alt-T is pressed.
 *
 * gcc -o ctrl-alt-t ctrl-alt-t.c -lX11
 *
 * Steve
 * --
 *
 * PS.  Use xbindkeys like a normal person ;)
 *
 */
}

{
Mask        | Value | Key
------------+-------+------------
ShiftMask   |     1 | Shift
LockMask    |     2 | Caps Lock
ControlMask |     4 | Ctrl
Mod1Mask    |     8 | Alt
Mod2Mask    |    16 | Num Lock
Mod3Mask    |    32 | Scroll Lock
Mod4Mask    |    64 | Windows
Mod5Mask    |   128 | ???
}

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

uses
unix,
xlib,
xutil,
keysym,
xfixes,
x;

var
d :  PXDisplay;
root : TWindow;
grab_window : TWindow absolute root;
keycode, rv : Int64;
m : DWord;
ev : TXEvent;
owner_events : LongInt = 0;
pointer_mode : LongInt = GrabModeAsync;
keyboard_mode : LongInt = GrabModeAsync;
modifiers : DWord = ControlMask or Mod1Mask;

begin
    d := XOpenDisplay(nil);
    root := DefaultRootWindow(d);
    keycode := XKeysymToKeycode(d,XK_Q);
{
    /**
     * OK this is unpleasant but we have to cope with XGrabKey.
     *
     * XGrabKey will let us listen for "keys" with "modifiers".  But only
     * exact matches will work.
     *
     * We want to be hit by Ctrl-Alt-t but what if the user has num-lock
     * on?  That will change the modifier.
     *
     * Similarly if capslock is on then our t becomes a T.  Obviously.
     *
     *
     * So we grab the key four times:
     *
     *    Ctrl + Alt + t
     *
     *    Ctrl + Alt + t + NumLock
     *
     *    Ctrl + Alt + t + CapsLock
     *
     *    Ctrl + Alt + t + NumLock + Capslock
     *
     * And that is the difference between reliable code and bogus code.
     *
     */
}

XGrabKey(d, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(d, keycode, modifiers or Mod2Mask, grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(d, keycode, modifiers or LockMask, grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(d, keycode, modifiers or LockMask or Mod2Mask, grab_window, owner_events, pointer_mode, keyboard_mode);

    XSelectInput(d, root, KeyPressMask);
    while true do begin
        XNextEvent(d, @ev);
        case(ev._type) of
        KeyPress: begin
WriteLn('kp = ',ev.xkey.keycode);
//                /**
//                 * We don't need to test the kind of key here since we've only
//                 * listened to one - albeit one with multiple modifier-masks
//                 */
                WriteLn(stderr, 'Launching terminal!');
                fpSystem('xterm');
        end;
        else
WriteLn('else');
        break;
        end;
    end;

    XCloseDisplay(d);
    Halt(0);
end.