| st-background-image-0.8.4.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| st-background-image-0.8.4.diff (7073B) | |
| --- | |
| 1 From 2c984d74ca15806dcfa174b7e75f48c0d01a49bf Mon Sep 17 00:00:00 2001 | |
| 2 From: Matthias Schoth <[email protected]> | |
| 3 Date: Thu, 17 Feb 2022 00:23:23 +0100 | |
| 4 Subject: [PATCH] Implements background image and pseudo transparancy sup… | |
| 5 | |
| 6 --- | |
| 7 config.def.h | 8 +++ | |
| 8 x.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++---- | |
| 9 2 files changed, 139 insertions(+), 10 deletions(-) | |
| 10 | |
| 11 diff --git a/config.def.h b/config.def.h | |
| 12 index 6f05dce..3d352db 100644 | |
| 13 --- a/config.def.h | |
| 14 +++ b/config.def.h | |
| 15 @@ -8,6 +8,14 @@ | |
| 16 static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohi… | |
| 17 static int borderpx = 2; | |
| 18 | |
| 19 +/* | |
| 20 + * background image | |
| 21 + * expects farbfeld format | |
| 22 + * pseudo transparency fixes coordinates to the screen origin | |
| 23 + */ | |
| 24 +static const char *bgfile = "/path/to/image.ff"; | |
| 25 +static const int pseudotransparency = 0; | |
| 26 + | |
| 27 /* | |
| 28 * What program is execed by st depends of these precedence rules: | |
| 29 * 1: program passed with -e | |
| 30 diff --git a/x.c b/x.c | |
| 31 index 210f184..5ecb8e5 100644 | |
| 32 --- a/x.c | |
| 33 +++ b/x.c | |
| 34 @@ -14,6 +14,7 @@ | |
| 35 #include <X11/keysym.h> | |
| 36 #include <X11/Xft/Xft.h> | |
| 37 #include <X11/XKBlib.h> | |
| 38 +#include <arpa/inet.h> | |
| 39 | |
| 40 char *argv0; | |
| 41 #include "arg.h" | |
| 42 @@ -81,6 +82,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; | |
| 43 typedef struct { | |
| 44 int tw, th; /* tty width and height */ | |
| 45 int w, h; /* window width and height */ | |
| 46 + int x, y; /* window location */ | |
| 47 int ch; /* char height */ | |
| 48 int cw; /* char width */ | |
| 49 int mode; /* window state/mode flags */ | |
| 50 @@ -101,6 +103,7 @@ typedef struct { | |
| 51 XVaNestedList spotlist; | |
| 52 } ime; | |
| 53 Draw draw; | |
| 54 + GC bggc; /* Graphics Context for background */ | |
| 55 Visual *vis; | |
| 56 XSetWindowAttributes attrs; | |
| 57 int scr; | |
| 58 @@ -151,6 +154,9 @@ static void ximinstantiate(Display *, XPointer, XPoi… | |
| 59 static void ximdestroy(XIM, XPointer, XPointer); | |
| 60 static int xicdestroy(XIC, XPointer, XPointer); | |
| 61 static void xinit(int, int); | |
| 62 +static void updatexy(void); | |
| 63 +static XImage *loadff(const char *); | |
| 64 +static void bginit(); | |
| 65 static void cresize(int, int); | |
| 66 static void xresize(int, int); | |
| 67 static void xhints(void); | |
| 68 @@ -502,6 +508,12 @@ propnotify(XEvent *e) | |
| 69 xpev->atom == clipboard)) { | |
| 70 selnotify(e); | |
| 71 } | |
| 72 + | |
| 73 + if (pseudotransparency && | |
| 74 + !strncmp(XGetAtomName(xw.dpy, e->xproperty.atom), "_NET_WM_… | |
| 75 + updatexy(); | |
| 76 + redraw(); | |
| 77 + } | |
| 78 } | |
| 79 | |
| 80 void | |
| 81 @@ -532,7 +544,8 @@ selnotify(XEvent *e) | |
| 82 return; | |
| 83 } | |
| 84 | |
| 85 - if (e->type == PropertyNotify && nitems == 0 && rem == … | |
| 86 + if (e->type == PropertyNotify && nitems == 0 && rem == … | |
| 87 + !pseudotransparency) { | |
| 88 /* | |
| 89 * If there is some PropertyNotify with no data… | |
| 90 * this is the signal of the selection owner th… | |
| 91 @@ -550,9 +563,11 @@ selnotify(XEvent *e) | |
| 92 * when the selection owner does send us the ne… | |
| 93 * chunk of data. | |
| 94 */ | |
| 95 - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMa… | |
| 96 - XChangeWindowAttributes(xw.dpy, xw.win, CWEvent… | |
| 97 + if (!pseudotransparency) { | |
| 98 + MODBIT(xw.attrs.event_mask, 1, Property… | |
| 99 + XChangeWindowAttributes(xw.dpy, xw.win,… | |
| 100 &xw.attrs); | |
| 101 + } | |
| 102 | |
| 103 /* | |
| 104 * Deleting the property is the transfer start … | |
| 105 @@ -820,9 +835,9 @@ xsetcolorname(int x, const char *name) | |
| 106 void | |
| 107 xclear(int x1, int y1, int x2, int y2) | |
| 108 { | |
| 109 - XftDrawRect(xw.draw, | |
| 110 - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defau… | |
| 111 - x1, y1, x2-x1, y2-y1); | |
| 112 + if (pseudotransparency) | |
| 113 + XSetTSOrigin(xw.dpy, xw.bggc, -win.x, -win.y); | |
| 114 + XFillRectangle(xw.dpy, xw.buf, xw.bggc, x1, y1, x2-x1, y2-y1); | |
| 115 } | |
| 116 | |
| 117 void | |
| 118 @@ -1207,6 +1222,100 @@ xinit(int cols, int rows) | |
| 119 xsel.xtarget = XA_STRING; | |
| 120 } | |
| 121 | |
| 122 +void | |
| 123 +updatexy() | |
| 124 +{ | |
| 125 + Window child; | |
| 126 + XTranslateCoordinates(xw.dpy, xw.win, DefaultRootWindow(xw.dpy)… | |
| 127 + &win.x, &win.y, &child); | |
| 128 +} | |
| 129 + | |
| 130 +/* | |
| 131 + * load farbfeld file to XImage | |
| 132 + */ | |
| 133 +XImage* | |
| 134 +loadff(const char *filename) | |
| 135 +{ | |
| 136 + uint32_t i, hdr[4], w, h, size; | |
| 137 + uint64_t *data; | |
| 138 + FILE *f = fopen(filename, "rb"); | |
| 139 + | |
| 140 + if (f == NULL) { | |
| 141 + fprintf(stderr, "could not load background image.\n"); | |
| 142 + return NULL; | |
| 143 + } | |
| 144 + | |
| 145 + if (fread(hdr, sizeof(*hdr), LEN(hdr), f) != LEN(hdr)) | |
| 146 + if (ferror(f)) { | |
| 147 + fprintf(stderr, "fread:"); | |
| 148 + return NULL; | |
| 149 + } | |
| 150 + else { | |
| 151 + fprintf(stderr, "fread: Unexpected end of file\… | |
| 152 + return NULL; | |
| 153 + } | |
| 154 + | |
| 155 + if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) { | |
| 156 + fprintf(stderr, "Invalid magic value"); | |
| 157 + return NULL; | |
| 158 + } | |
| 159 + | |
| 160 + w = ntohl(hdr[2]); | |
| 161 + h = ntohl(hdr[3]); | |
| 162 + size = w * h; | |
| 163 + data = malloc(size * sizeof(uint64_t)); | |
| 164 + | |
| 165 + if (fread(data, sizeof(uint64_t), size, f) != size) | |
| 166 + if (ferror(f)) { | |
| 167 + fprintf(stderr, "fread:"); | |
| 168 + return NULL; | |
| 169 + } | |
| 170 + else { | |
| 171 + fprintf(stderr, "fread: Unexpected end of file"… | |
| 172 + return NULL; | |
| 173 + } | |
| 174 + | |
| 175 + fclose(f); | |
| 176 + | |
| 177 + for (i = 0; i < size; i++) | |
| 178 + data[i] = (data[i] & 0x00000000000000FF) << 16 | | |
| 179 + (data[i] & 0x0000000000FF0000) >> 8 | | |
| 180 + (data[i] & 0x000000FF00000000) >> 32; | |
| 181 + | |
| 182 + XImage *xi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr), | |
| 183 + DefaultDepth(xw.dpy, xw.scr), ZPixm… | |
| 184 + (char *)data, w, h, 32, w * 8); | |
| 185 + xi->bits_per_pixel = 64; | |
| 186 + return xi; | |
| 187 +} | |
| 188 + | |
| 189 +/* | |
| 190 + * initialize background image | |
| 191 + */ | |
| 192 +void | |
| 193 +bginit() | |
| 194 +{ | |
| 195 + XGCValues gcvalues; | |
| 196 + Drawable bgimg; | |
| 197 + XImage *bgxi = loadff(bgfile); | |
| 198 + | |
| 199 + memset(&gcvalues, 0, sizeof(gcvalues)); | |
| 200 + xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues); | |
| 201 + if (!bgxi) return; | |
| 202 + bgimg = XCreatePixmap(xw.dpy, xw.win, bgxi->width, bgxi->height, | |
| 203 + DefaultDepth(xw.dpy, xw.scr)); | |
| 204 + XPutImage(xw.dpy, bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgxi->width, | |
| 205 + bgxi->height); | |
| 206 + XDestroyImage(bgxi); | |
| 207 + XSetTile(xw.dpy, xw.bggc, bgimg); | |
| 208 + XSetFillStyle(xw.dpy, xw.bggc, FillTiled); | |
| 209 + if (pseudotransparency) { | |
| 210 + updatexy(); | |
| 211 + MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); | |
| 212 + XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &x… | |
| 213 + } | |
| 214 +} | |
| 215 + | |
| 216 int | |
| 217 xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int l… | |
| 218 { | |
| 219 @@ -1447,7 +1556,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs… | |
| 220 xclear(winx, winy + win.ch, winx + width, win.h); | |
| 221 | |
| 222 /* Clean up the region we want to draw to. */ | |
| 223 - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); | |
| 224 + if (bg == &dc.col[defaultbg]) | |
| 225 + xclear(winx, winy, winx + width, winy + win.ch); | |
| 226 + else | |
| 227 + XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); | |
| 228 | |
| 229 /* Set the clip region because Xft is sometimes dirty. */ | |
| 230 r.x = 0; | |
| 231 @@ -1855,9 +1967,17 @@ cmessage(XEvent *e) | |
| 232 void | |
| 233 resize(XEvent *e) | |
| 234 { | |
| 235 - if (e->xconfigure.width == win.w && e->xconfigure.height == win… | |
| 236 - return; | |
| 237 - | |
| 238 + if (pseudotransparency) { | |
| 239 + if (e->xconfigure.width == win.w && | |
| 240 + e->xconfigure.height == win.h && | |
| 241 + e->xconfigure.x == win.x && e->xconfigure.y == win.… | |
| 242 + return; | |
| 243 + updatexy(); | |
| 244 + } else { | |
| 245 + if (e->xconfigure.width == win.w && | |
| 246 + e->xconfigure.height == win.h) | |
| 247 + return; | |
| 248 + } | |
| 249 cresize(e->xconfigure.width, e->xconfigure.height); | |
| 250 } | |
| 251 | |
| 252 @@ -2041,6 +2161,7 @@ run: | |
| 253 rows = MAX(rows, 1); | |
| 254 tnew(cols, rows); | |
| 255 xinit(cols, rows); | |
| 256 + bginit(); | |
| 257 xsetenv(); | |
| 258 selinit(); | |
| 259 run(); | |
| 260 -- | |
| 261 2.35.1 | |
| 262 |