dst/source/patch/background_image.d

148 lines
4.7 KiB
D
Raw Normal View History

2025-06-26 18:47:07 +00:00
module patch.background_image;
import st;
import x;
import config;
import patches;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import deimos.X11.Xlib;
import deimos.X11.X;
import deimos.X11.Xutil;
static if (isPatchEnabled!"BACKGROUND_IMAGE_PATCH") {
import core.sys.posix.arpa.inet : ntohl;
void updatexy() {
Window child;
XTranslateCoordinates(xw.dpy, xw.win, DefaultRootWindow(xw.dpy),
0, 0, &win.x, &win.y, &child);
}
/*
* load farbfeld file to XImage
*/
XImage* loadff(const(char)* filename) {
uint[4] hdr;
uint w, h, size;
ulong* data;
FILE* f = fopen(filename, "rb".ptr);
if (f is null) {
fprintf(stderr, "could not load background image.\n");
return null;
}
if (fread(hdr.ptr, uint.sizeof, hdr.length, f) != hdr.length) {
fprintf(stderr, "fread: %s\n", ferror(f) ? "".ptr : "Unexpected end of file reading header");
fclose(f);
return null;
}
if (memcmp("farbfeld".ptr, hdr.ptr, "farbfeld".length - 1) != 0) {
fprintf(stderr, "Invalid magic value\n");
fclose(f);
return null;
}
w = ntohl(hdr[2]);
h = ntohl(hdr[3]);
size = w * h;
data = cast(ulong*)xmalloc(size * ulong.sizeof);
if (fread(data, ulong.sizeof, size, f) != size) {
fprintf(stderr, "fread: %s\n", ferror(f) ? "".ptr : "Unexpected end of file reading data");
fclose(f);
free(data);
return null;
}
fclose(f);
for (uint i = 0; i < size; i++) {
data[i] = (data[i] & 0x00000000000000FF) << 16 |
(data[i] & 0x0000000000FF0000) >> 8 |
(data[i] & 0x000000FF00000000) >> 32 |
(data[i] & 0x00FF000000000000) >> 24;
}
static if (isPatchEnabled!"ALPHA_PATCH") {
XImage* xi = XCreateImage(xw.dpy, xw.vis, xw.depth, ZPixmap, 0,
cast(char*)data, w, h, 32, w * 8);
} else {
XImage* xi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr),
DefaultDepth(xw.dpy, xw.scr), ZPixmap, 0,
cast(char*)data, w, h, 32, w * 8);
}
xi.bits_per_pixel = 64;
return xi;
}
/*
* initialize background image
*/
extern(C) void bginit() {
XGCValues gcvalues;
Drawable bgimg;
XImage* bgxi = loadff(config.bgfile.ptr);
memset(&gcvalues, 0, XGCValues.sizeof);
xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues);
if (!bgxi)
return;
static if (isPatchEnabled!"ALPHA_PATCH") {
bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi.width, bgxi.height, xw.depth);
} else {
bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi.width, bgxi.height,
DefaultDepth(xw.dpy, xw.scr));
}
XPutImage(xw.dpy, bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgxi.width, bgxi.height);
XDestroyImage(bgxi);
XSetTile(xw.dpy, xw.bggc, bgimg);
XSetFillStyle(xw.dpy, xw.bggc, FillTiled);
if (config.pseudotransparency) {
updatexy();
xw.attrs.event_mask |= PropertyChangeMask;
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
}
}
static if (isPatchEnabled!"BACKGROUND_IMAGE_RELOAD_PATCH") {
void reload_image() {
XGCValues gcvalues;
Drawable bgimg;
// Recreate background GC
if (xw.bggc)
XFreeGC(xw.dpy, xw.bggc);
memset(&gcvalues, 0, XGCValues.sizeof);
xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues);
XImage* bgxi = loadff(config.bgfile.ptr);
if (!bgxi)
return;
static if (isPatchEnabled!"ALPHA_PATCH") {
bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi.width, bgxi.height, xw.depth);
} else {
bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi.width, bgxi.height,
DefaultDepth(xw.dpy, xw.scr));
}
XPutImage(xw.dpy, bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgxi.width, bgxi.height);
XDestroyImage(bgxi);
XSetTile(xw.dpy, xw.bggc, bgimg);
XSetFillStyle(xw.dpy, xw.bggc, FillTiled);
if (config.pseudotransparency) {
updatexy();
}
redraw();
}
}
}