#include "x11util.h"
extern "C" {
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <X11/extensions/scrnsaver.h>
}
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cstddef>
static int eHandler(Display* dpy, XErrorEvent* e)
{
char buf[1000];
XGetErrorText(dpy, e->error_code, buf, 1000);
fprintf(stderr, "X ERROR %d: %s\n", (int)e->error_code, buf);
return 0;
}
extern "C"
void AddPixmapToBackground(unsigned const char* imgData, const unsigned int width, const unsigned int height,
const unsigned int depth, const int bytesPerLine, const size_t byteCount)
{
Pixmap pix = 0;
GC gc = nullptr;
XImage *xi = nullptr;
XGCValues gc_init;
memset(&gc_init, 0, sizeof(gc_init));
Display* dpy = XOpenDisplay(nullptr);
if (dpy == nullptr)
return;
XSetErrorHandler(&eHandler);
int screen = DefaultScreen(dpy);
Window root = RootWindow(dpy, screen);
char *data = (char*)malloc(byteCount);
memcpy(data, imgData, byteCount);
xi = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, data, width, height, 32, bytesPerLine);
if (xi == nullptr)
goto cleanup;
pix = XCreatePixmap(dpy, root, width, height, (unsigned int)DefaultDepth(dpy, screen));
if (pix == 0)
goto cleanup;
gc_init.foreground = BlackPixel(dpy, screen);
gc_init.background = WhitePixel(dpy, screen);
gc = XCreateGC(dpy, pix, GCForeground|GCBackground, &gc_init);
if (gc == nullptr)
goto cleanup;
int res1, res2, res3;
res1 = XPutImage(dpy, pix, gc, xi, 0, 0, 0, 0, width, height);
res2 = XSetWindowBackgroundPixmap(dpy, root, pix);
res3 = XClearWindow(dpy, root);
cleanup:
if (gc != nullptr) {
XFreeGC(dpy, gc);
}
if (pix != 0) {
XFreePixmap(dpy, pix);
}
if (xi != nullptr) {
XDestroyImage(xi);
}
if (dpy != nullptr) {
XCloseDisplay(dpy);
}
}
extern "C"
unsigned int getKeyMask(Display *dpy)
{
unsigned int n = 0;
XkbGetIndicatorState(dpy, XkbUseCoreKbd, &n);
return n;
}
extern "C"
unsigned long getIdleTime(Display *dpy)
{
if (dpy == nullptr)
return 0;
int event_basep, error_basep;
XScreenSaverInfo *ssi = nullptr;
if (!XScreenSaverQueryExtension(dpy, &event_basep, &error_basep)) {
fprintf(stderr, "Screen saver extension not supported\n");
return 0;
}
ssi = XScreenSaverAllocInfo();
if (ssi == nullptr) {
fprintf(stderr, "Couldn't allocate screen saver info\n");
return 0;
}
if (!XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), ssi)) {
fprintf(stderr, "Couldn't query screen saver info\n");
return 0;
}
unsigned long idleTime = ssi->idle;
XFree(ssi);
return idleTime;
}