sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

st-background-image-0.8.4.diff (5333B)


      1 From fdf9692358326993f0dc6a6896cc0a7194ba6152 Mon Sep 17 00:00:00 2001
      2 From: Matthias Schoth <mschoth@gmail.com>
      3 Date: Sun, 4 Jul 2021 19:18:20 +0200
      4 Subject: [PATCH] Implements background image and pseudo transparancy support.
      5 
      6 ---
      7  config.def.h |  8 +++++
      8  x.c          | 91 ++++++++++++++++++++++++++++++++++++++++++++++++----
      9  2 files changed, 93 insertions(+), 6 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:autohint=true";
     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..22653ea 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,8 @@ typedef struct {
     51  		XVaNestedList spotlist;
     52  	} ime;
     53  	Draw draw;
     54 +	Drawable bgimg;   /* background image */
     55 +	GC bggc;          /* Graphics Context for background */
     56  	Visual *vis;
     57  	XSetWindowAttributes attrs;
     58  	int scr;
     59 @@ -151,6 +155,7 @@ static void ximinstantiate(Display *, XPointer, XPointer);
     60  static void ximdestroy(XIM, XPointer, XPointer);
     61  static int xicdestroy(XIC, XPointer, XPointer);
     62  static void xinit(int, int);
     63 +static void bginit();
     64  static void cresize(int, int);
     65  static void xresize(int, int);
     66  static void xhints(void);
     67 @@ -820,9 +825,9 @@ xsetcolorname(int x, const char *name)
     68  void
     69  xclear(int x1, int y1, int x2, int y2)
     70  {
     71 -	XftDrawRect(xw.draw,
     72 -			&dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg],
     73 -			x1, y1, x2-x1, y2-y1);
     74 +	if (pseudotransparency)
     75 +		XSetTSOrigin(xw.dpy, xw.bggc, -win.x, -win.y);
     76 +	XFillRectangle(xw.dpy, xw.buf, xw.bggc, x1, y1, x2-x1, y2-y1);
     77  }
     78  
     79  void
     80 @@ -1207,6 +1212,65 @@ xinit(int cols, int rows)
     81  		xsel.xtarget = XA_STRING;
     82  }
     83  
     84 +/*
     85 + * initialize background image
     86 + */
     87 +void
     88 +bginit()
     89 +{
     90 +	uint32_t hdr[4], bgw, bgh, i = 0;
     91 +	char buf[8], *image32;
     92 +	FILE *bgf = fopen(bgfile, "rb");
     93 +	XGCValues gcvalues;
     94 +	XImage *bgxi;
     95 +
     96 +	if (bgf == NULL) die("could not load background image.\n");
     97 +
     98 +	if (fread(hdr, sizeof(*hdr), LEN(hdr), bgf) != LEN(hdr))
     99 +		if (ferror(bgf))
    100 +			die("fread:");
    101 +		else
    102 +			die("fread: Unexpected end of file\n");
    103 +
    104 +	if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1))
    105 +		die("Invalid magic value");
    106 +
    107 +	bgw = ntohl(hdr[2]);
    108 +	bgh = ntohl(hdr[3]);
    109 +	image32 = (char *)malloc(bgw * bgh * 4 * sizeof(char));
    110 +
    111 +	while (i < bgh * bgw * 4) {
    112 +		if (fread(buf, sizeof(*buf), LEN(buf), bgf) != LEN(buf))
    113 +			if (ferror(bgf))
    114 +				die("fread:");
    115 +			else
    116 +				die("fread: Unexpected end of file");
    117 +
    118 +		image32[i++] = buf[4]; /* convert 16 bit RGBA to 8 bit BGRA */
    119 +		image32[i++] = buf[2];
    120 +		image32[i++] = buf[0];
    121 +		image32[i++] = buf[6];
    122 +        }
    123 +
    124 +	fclose(bgf);
    125 +	bgxi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr),
    126 +		24, ZPixmap, 0, image32, bgw, bgh, 32, 0);
    127 +	xw.bgimg = XCreatePixmap(xw.dpy, xw.win, bgw, bgh,
    128 +                        DefaultDepth(xw.dpy, xw.scr));
    129 +	XPutImage(xw.dpy, xw.bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgw, bgh);
    130 +	XDestroyImage(bgxi);
    131 +	memset(&gcvalues, 0, sizeof(gcvalues));
    132 +	xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues);
    133 +	XSetTile(xw.dpy, xw.bggc, xw.bgimg);
    134 +	XSetFillStyle(xw.dpy, xw.bggc, FillTiled);
    135 +	if (pseudotransparency) {
    136 +		XWindowAttributes xwa;
    137 +		XGetWindowAttributes(xw.dpy, xw.win, &xwa);
    138 +		win.x = xwa.x;
    139 +		win.y = xwa.y;
    140 +	}
    141 +}
    142 +
    143  int
    144  xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
    145  {
    146 @@ -1447,7 +1511,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
    147  		xclear(winx, winy + win.ch, winx + width, win.h);
    148  
    149  	/* Clean up the region we want to draw to. */
    150 -	XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
    151 +	if (bg == &dc.col[defaultbg])
    152 +		xclear(winx, winy, winx + width, winy + win.ch);
    153 +	else
    154 +		XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
    155  
    156  	/* Set the clip region because Xft is sometimes dirty. */
    157  	r.x = 0;
    158 @@ -1855,8 +1922,19 @@ cmessage(XEvent *e)
    159  void
    160  resize(XEvent *e)
    161  {
    162 -	if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
    163 -		return;
    164 +	if (pseudotransparency) {
    165 +		if (e->xconfigure.width == win.w &&
    166 +			e->xconfigure.height == win.h &&
    167 +			e->xconfigure.x == win.x && e->xconfigure.y == win.y)
    168 +			return;
    169 +
    170 +		win.x = e->xconfigure.x;
    171 +		win.y = e->xconfigure.y;
    172 +	} else {
    173 +		if (e->xconfigure.width == win.w &&
    174 +			e->xconfigure.height == win.h)
    175 +			return;
    176 +	}
    177  
    178  	cresize(e->xconfigure.width, e->xconfigure.height);
    179  }
    180 @@ -2041,6 +2119,7 @@ run:
    181  	rows = MAX(rows, 1);
    182  	tnew(cols, rows);
    183  	xinit(cols, rows);
    184 +	bginit();
    185  	xsetenv();
    186  	selinit();
    187  	run();
    188 -- 
    189 2.32.0
    190