8 #define FPTR(f) typeof(f) * p##f
9 #define FPTR_LINK(xf, dl, f) { \
10 xf.p##f = dlsym(dl, #f); \
11 if (xf.p##f == NULL) { \
12 fprintf(stderr, "missing symbol: %s\n", #f); \
18 FPTR(XCreateBitmapFromData);
19 FPTR(XCreatePixmapCursor);
24 FPTR(XCreateSimpleWindow);
25 FPTR(XChangeWindowAttributes);
29 FPTR(XCheckTypedEvent);
35 static Cursor transparent_cursor(struct xfuncs *xf, Display *display, Window win)
42 memset(&dummy, 0, sizeof(dummy));
43 pix = xf->pXCreateBitmapFromData(display, win, &d, 1, 1);
44 cursor = xf->pXCreatePixmapCursor(display, pix, pix,
45 &dummy, &dummy, 0, 0);
46 xf->pXFreePixmap(display, pix);
50 static void *x11h_handler(void *arg)
53 unsigned int display_width, display_height;
54 XSetWindowAttributes attributes;
62 memset(&xf, 0, sizeof(xf));
63 x11lib = dlopen("libX11.so.6", RTLD_LAZY);
65 fprintf(stderr, "libX11.so load failed:\n%s\n", dlerror());
68 FPTR_LINK(xf, x11lib, XCreateBitmapFromData);
69 FPTR_LINK(xf, x11lib, XCreatePixmapCursor);
70 FPTR_LINK(xf, x11lib, XFreePixmap);
71 FPTR_LINK(xf, x11lib, XOpenDisplay);
72 FPTR_LINK(xf, x11lib, XDisplayName);
73 FPTR_LINK(xf, x11lib, XCloseDisplay);
74 FPTR_LINK(xf, x11lib, XCreateSimpleWindow);
75 FPTR_LINK(xf, x11lib, XChangeWindowAttributes);
76 FPTR_LINK(xf, x11lib, XSelectInput);
77 FPTR_LINK(xf, x11lib, XMapWindow);
78 FPTR_LINK(xf, x11lib, XNextEvent);
79 FPTR_LINK(xf, x11lib, XCheckTypedEvent);
80 FPTR_LINK(xf, x11lib, XUnmapWindow);
81 FPTR_LINK(xf, x11lib, XGrabKeyboard);
85 display = xf.pXOpenDisplay(NULL);
88 fprintf(stderr, "cannot connect to X server %s, X handling disabled.\n",
89 xf.pXDisplayName(NULL));
93 visual = DefaultVisual(display, 0);
94 if (visual->class != TrueColor)
96 fprintf(stderr, "cannot handle non true color visual\n");
97 xf.pXCloseDisplay(display);
101 printf("x11h: X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
102 VendorRelease(display), DisplayString(display), ProtocolVersion(display),
103 ProtocolRevision(display));
105 screen = DefaultScreen(display);
107 display_width = DisplayWidth(display, screen);
108 display_height = DisplayHeight(display, screen);
109 printf("x11h: display is %dx%d\n", display_width, display_height);
111 win = xf.pXCreateSimpleWindow(display,
112 RootWindow(display, screen),
113 0, 0, display_width, display_height, 0,
114 BlackPixel(display, screen),
115 BlackPixel(display, screen));
117 attributes.override_redirect = True;
118 attributes.cursor = transparent_cursor(&xf, display, win);
119 xf.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
121 xf.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
122 xf.pXMapWindow(display, win);
123 xf.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
124 // XSetIOErrorHandler
128 xf.pXNextEvent(display, &report);
132 while (xf.pXCheckTypedEvent(display, Expose, &report))
138 // printf("focus out\n");
139 // xf.pXUnmapWindow(display, win);
143 // printf("press %d\n", report.xkey.keycode);
154 fprintf(stderr, "x11 handling disabled.\n");
163 ret = pthread_create(&tid, NULL, x11h_handler, NULL);
165 fprintf(stderr, "x11h: failed to create thread: %d\n", ret);