commit 6f5f7bec88bb2ea1b7d7b5e1f602d4b2d13e73f0
Author: Matthias Schoth <[email protected]>
Date:   Thu Feb 17 00:31:37 2022 +0100

    [st][patch][background_image] corrections and improvements
    
    - detect maximize/minimize events and refresh background position 
accordingly
    - more efficient farbfeld loading
    - don't exit on fail to load background, just print error
    - remove not needed global Drawable

diff --git 
a/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff 
b/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff
index 8a6b7bf1..f32c9476 100644
--- a/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff
+++ b/st.suckless.org/patches/background_image/st-background-image-0.8.4.diff
@@ -1,12 +1,12 @@
-From fdf9692358326993f0dc6a6896cc0a7194ba6152 Mon Sep 17 00:00:00 2001
+From 2c984d74ca15806dcfa174b7e75f48c0d01a49bf Mon Sep 17 00:00:00 2001
 From: Matthias Schoth <[email protected]>
-Date: Sun, 4 Jul 2021 19:18:20 +0200
+Date: Thu, 17 Feb 2022 00:23:23 +0100
 Subject: [PATCH] Implements background image and pseudo transparancy support.
 
 ---
- config.def.h |  8 +++++
- x.c          | 91 ++++++++++++++++++++++++++++++++++++++++++++++++----
- 2 files changed, 93 insertions(+), 6 deletions(-)
+ config.def.h |   8 +++
+ x.c          | 141 +++++++++++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 139 insertions(+), 10 deletions(-)
 
 diff --git a/config.def.h b/config.def.h
 index 6f05dce..3d352db 100644
@@ -28,7 +28,7 @@ index 6f05dce..3d352db 100644
   * What program is execed by st depends of these precedence rules:
   * 1: program passed with -e
 diff --git a/x.c b/x.c
-index 210f184..22653ea 100644
+index 210f184..5ecb8e5 100644
 --- a/x.c
 +++ b/x.c
 @@ -14,6 +14,7 @@
@@ -47,24 +47,62 @@ index 210f184..22653ea 100644
        int ch; /* char height */
        int cw; /* char width  */
        int mode; /* window state/mode flags */
-@@ -101,6 +103,8 @@ typedef struct {
+@@ -101,6 +103,7 @@ typedef struct {
                XVaNestedList spotlist;
        } ime;
        Draw draw;
-+      Drawable bgimg;   /* background image */
 +      GC bggc;          /* Graphics Context for background */
        Visual *vis;
        XSetWindowAttributes attrs;
        int scr;
-@@ -151,6 +155,7 @@ static void ximinstantiate(Display *, XPointer, XPointer);
+@@ -151,6 +154,9 @@ static void ximinstantiate(Display *, XPointer, XPointer);
  static void ximdestroy(XIM, XPointer, XPointer);
  static int xicdestroy(XIC, XPointer, XPointer);
  static void xinit(int, int);
++static void updatexy(void);
++static XImage *loadff(const char *);
 +static void bginit();
  static void cresize(int, int);
  static void xresize(int, int);
  static void xhints(void);
-@@ -820,9 +825,9 @@ xsetcolorname(int x, const char *name)
+@@ -502,6 +508,12 @@ propnotify(XEvent *e)
+                        xpev->atom == clipboard)) {
+               selnotify(e);
+       }
++
++      if (pseudotransparency &&
++          !strncmp(XGetAtomName(xw.dpy, e->xproperty.atom), "_NET_WM_STATE", 
13)) {
++              updatexy();
++              redraw();
++      }
+ }
+ 
+ void
+@@ -532,7 +544,8 @@ selnotify(XEvent *e)
+                       return;
+               }
+ 
+-              if (e->type == PropertyNotify && nitems == 0 && rem == 0) {
++              if (e->type == PropertyNotify && nitems == 0 && rem == 0 &&
++                  !pseudotransparency) {
+                       /*
+                        * If there is some PropertyNotify with no data, then
+                        * this is the signal of the selection owner that all
+@@ -550,9 +563,11 @@ selnotify(XEvent *e)
+                        * when the selection owner does send us the next
+                        * chunk of data.
+                        */
+-                      MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
+-                      XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask,
++                      if (!pseudotransparency) {
++                              MODBIT(xw.attrs.event_mask, 1, 
PropertyChangeMask);
++                              XChangeWindowAttributes(xw.dpy, xw.win, 
CWEventMask,
+                                       &xw.attrs);
++                      }
+ 
+                       /*
+                        * Deleting the property is the transfer start signal.
+@@ -820,9 +835,9 @@ xsetcolorname(int x, const char *name)
  void
  xclear(int x1, int y1, int x2, int y2)
  {
@@ -77,73 +115,108 @@ index 210f184..22653ea 100644
  }
  
  void
-@@ -1207,6 +1212,65 @@ xinit(int cols, int rows)
+@@ -1207,6 +1222,100 @@ xinit(int cols, int rows)
                xsel.xtarget = XA_STRING;
  }
  
++void
++updatexy()
++{
++      Window child;
++      XTranslateCoordinates(xw.dpy, xw.win, DefaultRootWindow(xw.dpy), 0, 0,
++                            &win.x, &win.y, &child);
++}
++
 +/*
-+ * initialize background image
++ * load farbfeld file to XImage
 + */
-+void
-+bginit()
++XImage*
++loadff(const char *filename)
 +{
-+      uint32_t hdr[4], bgw, bgh, i = 0;
-+      char buf[8], *image32;
-+      FILE *bgf = fopen(bgfile, "rb");
-+      XGCValues gcvalues;
-+      XImage *bgxi;
++      uint32_t i, hdr[4], w, h, size;
++      uint64_t *data;
++      FILE *f = fopen(filename, "rb");
 +
-+      if (bgf == NULL) die("could not load background image.
");
++      if (f == NULL) {
++              fprintf(stderr, "could not load background image.
");
++              return NULL;
++      }
 +
-+      if (fread(hdr, sizeof(*hdr), LEN(hdr), bgf) != LEN(hdr))
-+              if (ferror(bgf))
-+                      die("fread:");
-+              else
-+                      die("fread: Unexpected end of file
");
++      if (fread(hdr, sizeof(*hdr), LEN(hdr), f) != LEN(hdr))
++              if (ferror(f)) {
++                      fprintf(stderr, "fread:");
++                      return NULL;
++              }
++              else {
++                      fprintf(stderr, "fread: Unexpected end of file
");
++                      return NULL;
++              }
 +
-+      if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1))
-+              die("Invalid magic value");
++      if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
++              fprintf(stderr, "Invalid magic value");
++              return NULL;
++      }
 +
-+      bgw = ntohl(hdr[2]);
-+      bgh = ntohl(hdr[3]);
-+      image32 = (char *)malloc(bgw * bgh * 4 * sizeof(char));
++      w = ntohl(hdr[2]);
++      h = ntohl(hdr[3]);
++      size = w * h;
++      data = malloc(size * sizeof(uint64_t));
 +
-+      while (i < bgh * bgw * 4) {
-+              if (fread(buf, sizeof(*buf), LEN(buf), bgf) != LEN(buf))
-+                      if (ferror(bgf))
-+                              die("fread:");
-+                      else
-+                              die("fread: Unexpected end of file");
++      if (fread(data, sizeof(uint64_t), size, f) != size)
++              if (ferror(f)) {
++                      fprintf(stderr, "fread:");
++                      return NULL;
++              }
++              else {
++                      fprintf(stderr, "fread: Unexpected end of file");
++                      return NULL;
++              }
 +
-+              image32[i++] = buf[4]; /* convert 16 bit RGBA to 8 bit BGRA */
-+              image32[i++] = buf[2];
-+              image32[i++] = buf[0];
-+              image32[i++] = buf[6];
-+        }
++      fclose(f);
++
++      for (i = 0; i < size; i++)
++              data[i] = (data[i] & 0x00000000000000FF) << 16 |
++                        (data[i] & 0x0000000000FF0000) >> 8  |
++                        (data[i] & 0x000000FF00000000) >> 32;
++
++      XImage *xi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr),
++                                  DefaultDepth(xw.dpy, xw.scr), ZPixmap, 0,
++                                  (char *)data, w, h, 32, w * 8);
++      xi->bits_per_pixel = 64;
++      return xi;
++}
++
++/*
++ * initialize background image
++ */
++void
++bginit()
++{
++      XGCValues gcvalues;
++      Drawable bgimg;
++      XImage *bgxi = loadff(bgfile);
 +
-+      fclose(bgf);
-+      bgxi = XCreateImage(xw.dpy, DefaultVisual(xw.dpy, xw.scr),
-+              24, ZPixmap, 0, image32, bgw, bgh, 32, 0);
-+      xw.bgimg = XCreatePixmap(xw.dpy, xw.win, bgw, bgh,
-+                        DefaultDepth(xw.dpy, xw.scr));
-+      XPutImage(xw.dpy, xw.bgimg, dc.gc, bgxi, 0, 0, 0, 0, bgw, bgh);
-+      XDestroyImage(bgxi);
 +      memset(&gcvalues, 0, sizeof(gcvalues));
 +      xw.bggc = XCreateGC(xw.dpy, xw.win, 0, &gcvalues);
-+      XSetTile(xw.dpy, xw.bggc, xw.bgimg);
++      if (!bgxi) return;
++      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 (pseudotransparency) {
-+              XWindowAttributes xwa;
-+              XGetWindowAttributes(xw.dpy, xw.win, &xwa);
-+              win.x = xwa.x;
-+              win.y = xwa.y;
++              updatexy();
++              MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask);
++              XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
 +      }
 +}
 +
  int
  xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, 
int x, int y)
  {
-@@ -1447,7 +1511,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, 
Glyph base, int len, int x, i
+@@ -1447,7 +1556,10 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, 
Glyph base, int len, int x, i
                xclear(winx, winy + win.ch, winx + width, win.h);
  
        /* Clean up the region we want to draw to. */
@@ -155,29 +228,28 @@ index 210f184..22653ea 100644
  
        /* Set the clip region because Xft is sometimes dirty. */
        r.x = 0;
-@@ -1855,8 +1922,19 @@ cmessage(XEvent *e)
+@@ -1855,9 +1967,17 @@ cmessage(XEvent *e)
  void
  resize(XEvent *e)
  {
 -      if (e->xconfigure.width == win.w && e->xconfigure.height == win.h)
 -              return;
+-
 +      if (pseudotransparency) {
 +              if (e->xconfigure.width == win.w &&
-+                      e->xconfigure.height == win.h &&
-+                      e->xconfigure.x == win.x && e->xconfigure.y == win.y)
++                  e->xconfigure.height == win.h &&
++                  e->xconfigure.x == win.x && e->xconfigure.y == win.y)
 +                      return;
-+
-+              win.x = e->xconfigure.x;
-+              win.y = e->xconfigure.y;
++              updatexy();
 +      } else {
 +              if (e->xconfigure.width == win.w &&
-+                      e->xconfigure.height == win.h)
++                  e->xconfigure.height == win.h)
 +                      return;
 +      }
- 
        cresize(e->xconfigure.width, e->xconfigure.height);
  }
-@@ -2041,6 +2119,7 @@ run:
+ 
+@@ -2041,6 +2161,7 @@ run:
        rows = MAX(rows, 1);
        tnew(cols, rows);
        xinit(cols, rows);
@@ -186,5 +258,5 @@ index 210f184..22653ea 100644
        selinit();
        run();
 -- 
-2.32.0
+2.35.1
 


Reply via email to