#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>

#define error printf

int main(int argc, char **argv) {
  Display *dpy = XOpenDisplay(NULL);
  if (NULL == dpy) {
    error("XOpenDisplay(NULL) failed.\n");
    goto err_no_display;
  }
  printf("got display\n");
  int width = 640;
  int height = 480;
  // create window with attributes inherited from root window
  Window window = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
			       0, 0, width, height, 0, 0, 0);
  if (0 == window) {
    error("XCreateSimpleWindow() failed.\n");
    goto err_no_window;
  }
  printf("created window\n");
  // display window on screen
  // result checking of XMapWindow()?
  XMapWindow(dpy, window);
  printf("mapped window\n");

  XSelectInput(dpy, window, ExposureMask | KeyPressMask | StructureNotifyMask |
	       PointerMotionMask);
  Atom wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  XSetWMProtocols(dpy, window, &wm_delete_window, 1);
  printf("selected inputs\n");

  int grab = 0;

  while (1) {
    while (XPending(dpy)) {
      XEvent ev;
      XNextEvent(dpy, &ev);
      if (ev.xany.window == window) {
	XKeyEvent *keyEvent;
	XMotionEvent *pointerEvent;
	KeySym keySym;
	switch (ev.type) {
	case KeyPress:
	  keyEvent = (XKeyEvent*)(&ev);
	  keySym = XLookupKeysym(keyEvent, 0);
	  switch (keySym) {
	  case XK_Escape:
	    goto err_no_egldisplay;
	    break;
	  case XK_Return:
	    grab ^= 1;
	    if (grab)
	      XGrabPointer(dpy, window, True, 0, GrabModeAsync, GrabModeAsync,
			   window, None, CurrentTime);
	    else
	      XUngrabPointer(dpy, CurrentTime);
	    break;
	  }
	  break;
	case MotionNotify:
	  pointerEvent = (XMotionEvent*)(&ev);
	  printf("pointer at (%d, %d) rel (%d, %d)\n",
		 pointerEvent->x, pointerEvent->y, pointerEvent->x_root,
		 pointerEvent->y_root);
	  break;
	case ClientMessage:
	  goto err_no_egldisplay;
	  break;
	}
      }
    }
  }

 err_no_egldisplay:
  XUnmapWindow(dpy, window);
  XDestroyWindow(dpy, window);
 err_no_window:
  XCloseDisplay(dpy);
 err_no_display:
  return 0;
}
