148 lines
4.7 KiB
D
148 lines
4.7 KiB
D
|
|
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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|