st-background-image-0.8.4.diff 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. config.def.h | 8 +++++
  7. x.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++----
  8. 2 files changed, 93 insertions(+), 6 deletions(-)
  9. diff --git a/config.def.h b/config.def.h
  10. index 6f05dce..3d352db 100644
  11. --- a/config.def.h
  12. +++ b/config.def.h
  13. @@ -8,6 +8,14 @@
  14. static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
  15. static int borderpx = 2;
  16. +/*
  17. + * background image
  18. + * expects farbfeld format
  19. + * pseudo transparency fixes coordinates to the screen origin
  20. + */
  21. +static const char *bgfile = "/path/to/image.ff";
  22. +static const int pseudotransparency = 0;
  23. +
  24. /*
  25. * What program is execed by st depends of these precedence rules:
  26. * 1: program passed with -e
  27. diff --git a/x.c b/x.c
  28. index 210f184..22653ea 100644
  29. --- a/x.c
  30. +++ b/x.c
  31. @@ -14,6 +14,7 @@
  32. #include <X11/keysym.h>
  33. #include <X11/Xft/Xft.h>
  34. #include <X11/XKBlib.h>
  35. +#include <arpa/inet.h>
  36. char *argv0;
  37. #include "arg.h"
  38. @@ -81,6 +82,7 @@ typedef XftGlyphFontSpec GlyphFontSpec;
  39. typedef struct {
  40. int tw, th; /* tty width and height */
  41. int w, h; /* window width and height */
  42. + int x, y; /* window location */
  43. int ch; /* char height */
  44. int cw; /* char width */
  45. int mode; /* window state/mode flags */
  46. @@ -101,6 +103,8 @@ typedef struct {
  47. XVaNestedList spotlist;
  48. } ime;
  49. Draw draw;
  50. + Drawable bgimg; /* background image */
  51. + GC bggc; /* Graphics Context for background */
  52. Visual *vis;
  53. XSetWindowAttributes attrs;
  54. int scr;
  55. @@ -151,6 +155,7 @@ static void ximinstantiate(Display *, XPointer, XPointer);
  56. static void ximdestroy(XIM, XPointer, XPointer);
  57. static int xicdestroy(XIC, XPointer, XPointer);
  58. static void xinit(int, int);
  59. +static void bginit();
  60. static void cresize(int, int);
  61. static void xresize(int, int);
  62. static void xhints(void);
  63. @@ -820,9 +825,9 @@ xsetcolorname(int x, const char *name)
  64. void
  65. xclear(int x1, int y1, int x2, int y2)
  66. {
  67. - XftDrawRect(xw.draw,
  68. - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg],
  69. - x1, y1, x2-x1, y2-y1);
  70. + if (pseudotransparency)
  71. + XSetTSOrigin(xw.dpy, xw.bggc, -win.x, -win.y);
  72. + XFillRectangle(xw.dpy, xw.buf, xw.bggc, x1, y1, x2-x1, y2-y1);
  73. }
  74. void
  75. @@ -1207,6 +1212,65 @@ xinit(int cols, int rows)
  76. xsel.xtarget = XA_STRING;
  77. }
  78. +/*
  79. + * initialize background image
  80. + */
  81. +void
  82. +bginit()
  83. +{
  84. + uint32_t hdr[4], bgw, bgh, i = 0;
  85. + char buf[8], *image32;
  86. + FILE *bgf = fopen(bgfile, "rb");
  87. + XGCValues gcvalues;
  88. + XImage *bgxi;
  89. +
  90. + if (bgf == NULL) die("could not load background image.\n");
  91. +
  92. + if (fread(hdr, sizeof(*hdr), LEN(hdr), bgf) != LEN(hdr))
  93. + if (ferror(bgf))
  94. + die("fread:");
  95. + else
  96. + die("fread: Unexpected end of file\n");
  97. +
  98. + if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1))
  99. + die("Invalid magic value");
  100. +
  101. + bgw = ntohl(hdr[2]);
  102. + bgh = ntohl(hdr[3]);
  103. + image32 = (char *)malloc(bgw * bgh * 4 * sizeof(char));
  104. +
  105. + while (i < bgh * bgw * 4) {
  106. + if (fread(buf, sizeof(*buf), LEN(buf), bgf) != LEN(buf))
  107. + if (ferror(bgf))
  108. + die("fread:");
  109. + else
  110. + die("fread: Unexpected end of file");
  111. +
  112. + image32[i++] = buf[4]; /* convert 16 bit RGBA to 8 bit BGRA */
  113. + image32[i++] = buf[2];
  114. + image32[i++] = buf[0];
  115. + image32[i++] = buf[6];
  116. + }
  117. +
  118. + fclose(bgf);
  119. + bgxi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr),
  120. + 24, ZPixmap, 0, image32, bgw, bgh, 32, 0);
  121. + xw.bgimg = XCreatePixmap(xw.dpy, xw.win, bgw, bgh,
  122. + DefaultDepth(xw.dpy, xw.scr));
  123. + XPutImage(xw.dpy, xw.bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgw, bgh);
  124. + XDestroyImage(bgxi);
  125. + memset(&gcvalues, 0, sizeof(gcvalues));
  126. + xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues);
  127. + XSetTile(xw.dpy, xw.bggc, xw.bgimg);
  128. + XSetFillStyle(xw.dpy, xw.bggc, FillTiled);
  129. + if (pseudotransparency) {
  130. + XWindowAttributes xwa;
  131. + XGetWindowAttributes(xw.dpy, xw.win, &xwa);
  132. + win.x = xwa.x;
  133. + win.y = xwa.y;
  134. + }
  135. +}
  136. +
  137. int
  138. xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
  139. {
  140. @@ -1447,7 +1511,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
  141. xclear(winx, winy + win.ch, winx + width, win.h);
  142. /* Clean up the region we want to draw to. */
  143. - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
  144. + if (bg == &dc.col[defaultbg])
  145. + xclear(winx, winy, winx + width, winy + win.ch);
  146. + else
  147. + XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
  148. /* Set the clip region because Xft is sometimes dirty. */
  149. r.x = 0;
  150. @@ -1855,8 +1922,19 @@ cmessage(XEvent *e)
  151. void
  152. resize(XEvent *e)
  153. {
  154. - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
  155. - return;
  156. + if (pseudotransparency) {
  157. + if (e->xconfigure.width == win.w &&
  158. + e->xconfigure.height == win.h &&
  159. + e->xconfigure.x == win.x && e->xconfigure.y == win.y)
  160. + return;
  161. +
  162. + win.x = e->xconfigure.x;
  163. + win.y = e->xconfigure.y;
  164. + } else {
  165. + if (e->xconfigure.width == win.w &&
  166. + e->xconfigure.height == win.h)
  167. + return;
  168. + }
  169. cresize(e->xconfigure.width, e->xconfigure.height);
  170. }
  171. @@ -2041,6 +2119,7 @@ run:
  172. rows = MAX(rows, 1);
  173. tnew(cols, rows);
  174. xinit(cols, rows);
  175. + bginit();
  176. xsetenv();
  177. selinit();
  178. run();
  179. --
  180. 2.32.0