{$MODE OBJFPC}
program xwin;

uses x,xlib, keysym, classes, sysutils;

type
  TWindow = class
  private
    display       : pDisplay;
    RootWindow    : TWindow;
    CurrentWindow : TWindow;
  public
    constructor create(display_link : PChar);
    destructor destroy; override;
    procedure execute;
  end;

constructor TWindow.create(display_link : PChar);
begin
  self.display := XOpenDisplay(display_link); // lets get the x-server connection

  if (display = nil) then
    raise Exception.CreateFmt('Unable to open a display at %s.', [display_link]);

  self.RootWindow    := TWindow(XDefaultRootWindow(self.display)); // Get the root window (sometimes the desktop...)
  //                                   Display pointer     Window pointer    x  y   w    h
  self.CurrentWindow := Twindow(XCreateSimpleWindow(self.display,  QWord(self.RootWindow),  0, 0, 100, 200,
                                       1,  // Border width
                                       10, // Border
                                       XWhitePixel(self.display, 0))); // Background color <- on a regular xlib app, you should use XWhitePixel and XBlackPixel only once, so save the value in a variable
  // set events 
  XSelectInput(self.display, QWord(self.CurrentWindow),
               KeyPressMask); // what event to read...

  // set the window in x11
  XMapWindow(self.display, QWord(self.CurrentWindow));
end;

destructor TWindow.destroy;
begin
  XDestroyWindow(self.display, Qword(self.CurrentWindow));
  XCloseDisplay(self.display);
  inherited;
end;


procedure TWindow.execute;
var
  Events_Status : TXEvent; // event
  Key           : Tkeysym; // key
  ToBreak       : Boolean;
begin
  ToBreak := false;
  while (not ToBreak) do
   begin
     XNextEvent(self.display, @Events_Status);
     case Events_Status._type of
       KeyPress : begin
                   Key := XKeycodeToKeysym(self.display, Events_Status.xkey.keycode, 0); // convert regular keybard to Xkeyscan code
                   case Key of 
                     XK_Escape : ToBreak := true;
                   else writeln('The user is pressing on ', XKeysymToString (Key)); // display what is the key name 
                   end;
                  end;
       else XFlush(self.display); // paint the window on screen
     end;
   end;
end;

var
  Window : TWindow;

begin
  Window := TWindow.Create(':0');
  try
    Window.Execute;
  finally
    Window.Free;
  end;
end.

