commit - 15f3a3a2f5fe4fb609bf560f1cd26ac8907a24c8
commit + 8917670ecee53ffd46e89f1ac22ffe9ecf5090e1
blob - cbfb9ef599eeff12bd160d287b1a825a53164915
blob + bededa2e85204ddaa587830d57929b26e88f6a40
--- Makefile
+++ Makefile
MAN = dwm/dwm.1 st/st.1 dmenu/dmenu.1 dmenu/stest.1
-all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest
+all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest bin/xbgcd
clean:
rm -rf bin
@mkdir -p bin
${CC} -o $@ ${SRC_STEST} ${CFLAGS}
+bin/xbgcd: xbgcd/xbgcd.c
+ @mkdir -p bin
+ ${CC} -o $@ xbgcd/xbgcd.c ${CFLAGS} `pkg-config --cflags --libs x11`
+
.PHONY: all clean install
blob - 424ce83fa920781beb8cd499a0f309d9818bcf88
blob + b45a56b765d53dd6b0f39145b3f8774bf4e88fab
--- TODO
+++ TODO
# Import
- surf
- tabbed
-- xbgcd
- slock
- nsxiv
blob - /dev/null
blob + 1b12b24364134eaa04e79f3b3384c3405190386d (mode 644)
--- /dev/null
+++ xbgcd/LICENSE
+MIT/X Consortium License
+
+© 2022 Benjamin Stürz <benni@stuerz.xyz>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
blob - /dev/null
blob + d9731410f1b432c39c46631480e57c66dcc3b0ca (mode 644)
--- /dev/null
+++ xbgcd/config.h
+
+// Define the color steps.
+static const struct MyColor steps[] = {
+ { 1.0, 0.0, 0.0 },
+ { 0.0, 1.0, 0.0 },
+ { 0.0, 0.0, 1.0 },
+};
+
+// The initial background color.
+static const struct MyColor initial_color = { 0.5, 0.5, 0.5 };
+
+// Interpolation increent per substep.
+static const float sub_step_inc = 0.01f;
+
+// Delay (in milliseconds) between substeps.
+static const unsigned delay = 100;
blob - /dev/null
blob + d36d9c8c5fde5ad200f4e2a9f61d9ffa16ae67a9 (mode 644)
--- /dev/null
+++ xbgcd/xbgcd.c
+/* See LICENSE file for copyright and license details.
+ *
+ * X background color daemon is really simple. It just uses interpolation
+ * between steps to get the new background color. If the substep reaches 1.0f,
+ * it resets it, and starts the next step.
+ */
+#include <X11/Xlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+struct MyColor {
+ float r, g, b;
+};
+
+#include "config.h"
+
+const size_t num_steps = (sizeof steps) / (sizeof *steps);
+
+static Display *dpy;
+static int screen;
+static Window root;
+
+static unsigned long MyColorToPixel (const struct MyColor *color);
+static unsigned long NameToPixel (const char *color);
+static void FillBackground (const struct MyColor *color);
+static void die (const char *s);
+
+int
+main(int argc, char *argv[])
+{
+ if (argc == 2 && !strcmp (argv[1], "-v")) {
+ die ("xkbcd-" VERSION);
+ } else if (argc != 1) {
+ die ("usage: xbcd [-v]");
+ }
+
+ dpy = XOpenDisplay (NULL);
+ if (!dpy)
+ die ("xkbcd: unable to open display");
+
+#ifdef __OpenBSD__
+ if (pledge ("stdio", NULL) == -1)
+ die ("pledge");
+#endif // __OpenBSD__
+
+ screen = DefaultScreen (dpy);
+ root = RootWindow (dpy, screen);
+
+ size_t step = 0;
+ float sub_step = 0.0f;
+ struct MyColor prev = initial_color;
+
+ while (1) {
+ const struct MyColor cur = steps[step];
+ const struct MyColor c = {
+ .r = prev.r + (cur.r - prev.r) * sub_step,
+ .g = prev.g + (cur.g - prev.g) * sub_step,
+ .b = prev.b + (cur.b - prev.b) * sub_step,
+ };
+
+ FillBackground (&c);
+
+ sub_step += sub_step_inc;
+
+ if (sub_step > 1.0f) {
+ step = (step + 1) % num_steps;
+ prev = cur;
+ sub_step -= 1.0f;
+ }
+ usleep (delay * 1000);
+ }
+ XCloseDisplay (dpy);
+ return 0;
+}
+
+static unsigned long
+MyColorToPixel (const struct MyColor *color)
+{
+ char str[8];
+ const int r = (int)(color->r * 255.0f);
+ const int g = (int)(color->g * 255.0f);
+ const int b = (int)(color->b * 255.0f);
+
+ snprintf (str, sizeof str, "#%02X%02X%02X", r, g, b);
+
+ return NameToPixel (str);
+}
+
+// This function is taken from xsetroot: https://github.com/freedesktop/xorg-xsetroot/blob/master/xsetroot.c
+static unsigned long
+NameToPixel (const char *name)
+{
+ XColor ecolor;
+
+ if (!name || !*name)
+ return BlackPixel (dpy, screen);
+
+ Colormap colormap = DefaultColormap (dpy, screen);
+
+ if (!XParseColor (dpy, colormap, name, &ecolor)) {
+ fprintf (stderr, "xbgcd: unknown color '%s'\n", name);
+ return BlackPixel (dpy, screen);
+ }
+
+ if (!XAllocColor (dpy, colormap, &ecolor)) {
+ fprintf (stderr, "xbgcd: unable to allocate color for '%s'\n", name);
+ return BlackPixel (dpy, screen);
+ }
+
+ return ecolor.pixel;
+}
+
+static void
+FillBackground (const struct MyColor *color)
+{
+ unsigned long pixel = MyColorToPixel (color);
+ XSetWindowBackground (dpy, root, pixel);
+ XClearWindow (dpy, root);
+ XFlush (dpy);
+}
+
+static void
+die (const char *s)
+{
+ fprintf (stderr, "%s\n", s);
+ exit (1);
+}